Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 263263 Details for
Bug 491261
Merge DotImport and DotInterpreter into a single Xtend-based DotImport (comparable to DotExport)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Patch representing integrating the DotInterpreter into the DotImport
491261-Merge-DotInterpreter-into-DotImport.patch (text/plain), 60.23 KB, created by
Tamas Miklossy
on 2016-07-22 09:46:16 EDT
(
hide
)
Description:
Patch representing integrating the DotInterpreter into the DotImport
Filename:
MIME Type:
Creator:
Tamas Miklossy
Created:
2016-07-22 09:46:16 EDT
Size:
60.23 KB
patch
obsolete
>diff --git a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/AllTests.java b/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/AllTests.java >index 9c3eb95..8fbbaa4 100644 >--- a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/AllTests.java >+++ b/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/AllTests.java >@@ -8,6 +8,7 @@ > * > * Contributors: > * Alexander NyÃen (itemis AG) - initial API and implementation >+ * Tamas Miklossy (itemis AG) - merge DotInterpreter into DotImport (bug #491261) > * > *******************************************************************************/ > package org.eclipse.gef4.dot.tests; >@@ -18,8 +19,8 @@ > > @RunWith(Suite.class) > @SuiteClasses({ DotImportTests.class, DotExportTests.class, >- DotExecutableUtilsTests.class, DotInterpreterTests.class, >- DotExtractorTests.class, DotAttributesTests.class, DotParserTests.class, >+ DotExecutableUtilsTests.class, DotExtractorTests.class, >+ DotAttributesTests.class, DotParserTests.class, > DotValidatorTests.class }) > public class AllTests { > >diff --git a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotImportTests.java b/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotImportTests.java >index 92c23fc..79c05a4 100644 >--- a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotImportTests.java >+++ b/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotImportTests.java >@@ -9,16 +9,21 @@ > * Contributors: > * Fabian Steeg - initial API and implementation (see bug #277380) > * Tamas Miklossy (itemis AG) - implement additional test cases (bug #493136) >+ * - merge DotInterpreter into DotImport (bug #491261) > * > *******************************************************************************/ > package org.eclipse.gef4.dot.tests; > > import static org.eclipse.gef4.dot.tests.DotTestUtils.RESOURCES_TESTS; >+import static org.junit.Assert.assertEquals; > > import java.io.File; >+import java.util.List; > > import org.eclipse.gef4.dot.internal.DotAttributes; > import org.eclipse.gef4.dot.internal.DotImport; >+import org.eclipse.gef4.dot.internal.parser.layout.Layout; >+import org.eclipse.gef4.dot.internal.parser.rankdir.Rankdir; > import org.eclipse.gef4.graph.Edge; > import org.eclipse.gef4.graph.Graph; > import org.eclipse.gef4.graph.Node; >@@ -30,15 +35,15 @@ > * > * @author Fabian Steeg (fsteeg) > */ >-// TODO: this could be combined with the DotInterpreterTests, similar >-// as DotExportTests and DotTemplateTests > public final class DotImportTests { >+ >+ private final DotImport dotImport = new DotImport(); > > private Graph testFileImport(final File dotFile) { > Assert.assertTrue("DOT input file must exist: " + dotFile, //$NON-NLS-1$ > dotFile.exists()); >- Graph graph = new DotImport().importDot(dotFile); >- Assert.assertNotNull("Resulting graph must not be null", graph); //$NON-NLS-1$ >+ Graph graph = dotImport.importDot(dotFile); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ > return graph; > } > >@@ -85,7 +90,282 @@ > */ > @Test(expected = IllegalArgumentException.class) > public void invalidGraphFileImport() { >- new DotImport().importDot("graph Sample{"); >+ dotImport.importDot("graph Sample{"); >+ } >+ >+ @Test(expected = IllegalArgumentException.class) >+ public void faultyLayout() { >+ dotImport.importDot("graph Sample{graph[layout=cool];1;}"); //$NON-NLS-1$ >+ } >+ >+ @Test >+ public void digraphType() { >+ Graph graph = dotImport >+ .importDot(DotTestGraphs.TWO_NODES_ONE_DIRECTED_EDGE); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(DotAttributes._TYPE__G__DIGRAPH, >+ DotAttributes._getType(graph)); >+ } >+ >+ @Test >+ public void graphType() { >+ Graph graph = dotImport.importDot(DotTestGraphs.TWO_NODES_ONE_EDGE); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(DotAttributes._TYPE__G__GRAPH, >+ DotAttributes._getType(graph)); >+ } >+ >+ @Test >+ public void nodeDefaultLabel() { >+ Graph graph = dotImport.importDot(DotTestGraphs.ONE_NODE); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals("1", //$NON-NLS-1$ >+ DotAttributes._getName(graph.getNodes().get(0))); >+ } >+ >+ @Test >+ public void nodeCount() { >+ Graph graph = dotImport.importDot(DotTestGraphs.TWO_NODES); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(2, graph.getNodes().size()); >+ } >+ >+ @Test >+ public void edgeCount() { >+ Graph graph = dotImport >+ .importDot(DotTestGraphs.TWO_NODES_AND_THREE_EDGES); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(3, graph.getEdges().size()); >+ } >+ >+ @Test >+ public void layoutSpring() { >+ Graph graph = dotImport.importDot(DotTestGraphs.GRAPH_LAYOUT_FDP); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(Layout.FDP.toString(), >+ DotAttributes.getLayout(graph)); >+ } >+ >+ @Test >+ public void layoutGrid() { >+ Graph graph = dotImport.importDot(DotTestGraphs.GRAPH_LAYOUT_OSAGE); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(Layout.OSAGE.toString(), >+ DotAttributes.getLayout(graph)); >+ } >+ >+ @Test >+ public void layoutRadial() { >+ Graph graph = dotImport.importDot(DotTestGraphs.GRAPH_LAYOUT_TWOPI); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(Layout.TWOPI.toString(), >+ DotAttributes.getLayout(graph)); >+ } >+ >+ @Test >+ public void layoutTree() { >+ Graph graph = dotImport.importDot(DotTestGraphs.GRAPH_LAYOUT_DOT); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(Layout.DOT.toString(), >+ DotAttributes.getLayout(graph)); >+ } >+ >+ @Test >+ public void layoutHorizontalTreeViaLayout() { >+ Graph graph = dotImport >+ .importDot(DotTestGraphs.GRAPH_LAYOUT_DOT_HORIZONTAL); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(Layout.DOT.toString(), >+ DotAttributes.getLayout(graph)); >+ Assert.assertEquals(Rankdir.LR, DotAttributes.getRankdirParsed(graph)); >+ } >+ >+ @Test >+ public void layoutHorizontalTreeViaAttribute() { >+ Graph graph = dotImport.importDot(DotTestGraphs.GRAPH_RANKDIR_LR); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(Rankdir.LR, DotAttributes.getRankdirParsed(graph)); >+ } >+ >+ @Test >+ public void globalNodeAttributeAdHocNodes() { >+ Graph graph = dotImport >+ .importDot(DotTestGraphs.GLOBAL_NODE_LABEL_AD_HOC_NODES); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals("TEXT", //$NON-NLS-1$ >+ DotAttributes.getLabel(graph.getNodes().get(0))); >+ } >+ >+ @Test >+ public void globalEdgeAttributeAdHocNodes() { >+ Graph graph = dotImport >+ .importDot(DotTestGraphs.GLOBAL_EDGE_LABEL_AD_HOC_NODES); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals("TEXT", DotAttributes.getLabel(graph.getEdges() //$NON-NLS-1$ >+ .get(0))); >+ } >+ >+ @Test >+ public void headerCommentGraph() { >+ Graph graph = dotImport.importDot(DotTestGraphs.HEADER_COMMENT); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(2, graph.getNodes().size()); >+ Assert.assertEquals(1, graph.getEdges().size()); >+ } >+ >+ @Test >+ public void nodesBeforeEdges() { >+ Graph.Builder graph = new Graph.Builder().attr(DotAttributes._TYPE__G, >+ DotAttributes._TYPE__G__GRAPH); >+ Node[] nodes = createNodes(); >+ Edge e1 = new Edge.Builder(nodes[0], nodes[1]) >+ .attr(DotAttributes._NAME__GNE, "1--2") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e2 = new Edge.Builder(nodes[1], nodes[2]) >+ .attr(DotAttributes._NAME__GNE, "2--3") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e3 = new Edge.Builder(nodes[1], nodes[3]) >+ .attr(DotAttributes._NAME__GNE, "2--4") //$NON-NLS-1$ >+ .buildEdge(); >+ Graph expected = graph.nodes(nodes).edges(e1, e2, e3).build(); >+ testStringImport(expected, DotTestGraphs.NODES_BEFORE_EDGES); >+ } >+ >+ @Test >+ public void nodesAfterEdges() { >+ Graph.Builder graph = new Graph.Builder().attr(DotAttributes._TYPE__G, >+ DotAttributes._TYPE__G__GRAPH); >+ Node[] nodes = createNodes(); >+ DotAttributes.setLabel(nodes[0], "node"); >+ Edge e1 = new Edge.Builder(nodes[0], nodes[1]) >+ .attr(DotAttributes._NAME__GNE, "1--2") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e2 = new Edge.Builder(nodes[1], nodes[2]) >+ .attr(DotAttributes._NAME__GNE, "2--3") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e3 = new Edge.Builder(nodes[1], nodes[3]) >+ .attr(DotAttributes._NAME__GNE, "2--4") //$NON-NLS-1$ >+ .buildEdge(); >+ Graph expected = graph.nodes(nodes).edges(e1, e2, e3).build(); >+ testStringImport(expected, DotTestGraphs.NODES_AFTER_EDGES); >+ } >+ >+ @Test >+ public void useDotImporterTwice() { >+ String dot = DotTestGraphs.NODES_AFTER_EDGES; >+ Graph graph = dotImport.importDot(dot); >+ graph = dotImport.importDot(dot); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(4, graph.getNodes().size()); >+ Assert.assertEquals(3, graph.getEdges().size()); >+ } >+ >+ @Test >+ public void idsWithQuotes() { >+ Graph graph = dotImport.importDot(DotTestGraphs.IDS_WITH_QUOTES); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ List<Node> list = graph.getNodes(); >+ Assert.assertEquals("node 1", //$NON-NLS-1$ >+ DotAttributes._getName(list.get(0))); >+ Assert.assertEquals("node 2", //$NON-NLS-1$ >+ DotAttributes._getName(list.get(1))); >+ } >+ >+ @Test >+ public void escapedQuotes() { >+ Graph graph = dotImport.importDot(DotTestGraphs.ESCAPED_QUOTES_LABEL); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals("node \"1\"", //$NON-NLS-1$ >+ DotAttributes.getLabel(graph.getNodes().get(0))); >+ } >+ >+ @Test >+ public void fullyQuoted() { >+ Graph graph = dotImport.importDot(DotTestGraphs.FULLY_QUOTED_IDS); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals(2, graph.getNodes().size()); >+ Assert.assertEquals(1, graph.getEdges().size()); >+ List<Node> list = graph.getNodes(); >+ Assert.assertEquals("n1", //$NON-NLS-1$ >+ DotAttributes._getName(list.get(0))); >+ Assert.assertEquals("n2", //$NON-NLS-1$ >+ DotAttributes._getName(list.get(1))); >+ } >+ >+ @Test >+ public void labelsWithQuotes() { >+ Graph graph = dotImport.importDot(DotTestGraphs.QUOTED_LABELS); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ List<Node> list = graph.getNodes(); >+ Assert.assertEquals("node 1", //$NON-NLS-1$ >+ DotAttributes.getLabel(list.get(0))); >+ Assert.assertEquals("node 2", //$NON-NLS-1$ >+ DotAttributes.getLabel(list.get(1))); >+ Assert.assertEquals("edge 1", >+ DotAttributes.getLabel(graph.getEdges().get(0))); >+ } >+ >+ @Test >+ public void newLinesInLabels() { >+ Graph graph = dotImport.importDot(DotTestGraphs.NEW_LINES_IN_LABELS); >+ Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >+ Assert.assertEquals("node" + System.lineSeparator() + "1", //$NON-NLS-1$ >+ DotAttributes.getLabel(graph.getNodes().get(0))); >+ } >+ >+ @Test >+ public void multiEdgeStatements() { >+ // test global attribute >+ Graph.Builder graph = new Graph.Builder().attr(DotAttributes._TYPE__G, >+ DotAttributes._TYPE__G__DIGRAPH); >+ Node[] nodes = createNodes(); >+ Edge e1 = new Edge.Builder(nodes[0], nodes[1]) >+ .attr(DotAttributes._NAME__GNE, "1->2") //$NON-NLS-1$ >+ .attr(DotAttributes.ARROWHEAD__E, "ornormal") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e2 = new Edge.Builder(nodes[1], nodes[2]) >+ .attr(DotAttributes._NAME__GNE, "2->3") //$NON-NLS-1$ >+ .attr(DotAttributes.ARROWHEAD__E, "ornormal") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e3 = new Edge.Builder(nodes[2], nodes[3]) >+ .attr(DotAttributes._NAME__GNE, "3->4") //$NON-NLS-1$ >+ .attr(DotAttributes.ARROWHEAD__E, "ornormal") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e4 = new Edge.Builder(nodes[0], nodes[1]) >+ .attr(DotAttributes._NAME__GNE, "1->2") //$NON-NLS-1$ >+ .attr(DotAttributes.ARROWHEAD__E, "ornormal") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e5 = new Edge.Builder(nodes[1], nodes[2]) >+ .attr(DotAttributes._NAME__GNE, "2->3") //$NON-NLS-1$ >+ .attr(DotAttributes.ARROWHEAD__E, "ornormal") //$NON-NLS-1$ >+ .buildEdge(); >+ Edge e6 = new Edge.Builder(nodes[2], nodes[3]) >+ .attr(DotAttributes._NAME__GNE, "3->4") //$NON-NLS-1$ >+ .attr(DotAttributes.ARROWHEAD__E, "ornormal") //$NON-NLS-1$ >+ .buildEdge(); >+ Graph expected = graph.nodes(nodes).edges(e1, e2, e3, e4, e5, e6) >+ .build(); >+ testStringImport(expected, DotTestGraphs.MULTI_EDGE_STATEMENTS_GLOBAL); >+ >+ // test local attribute >+ graph = new Graph.Builder().attr(DotAttributes._TYPE__G, >+ DotAttributes._TYPE__G__DIGRAPH); >+ DotAttributes.setArrowHead(e4, "olnormal"); >+ DotAttributes.setArrowHead(e5, "olnormal"); >+ DotAttributes.setArrowHead(e6, "olnormal"); >+ expected = graph.nodes(nodes).edges(e1, e2, e3, e4, e5, e6).build(); >+ testStringImport(expected, DotTestGraphs.MULTI_EDGE_STATEMENTS_LOCAL); >+ >+ // test override attribute >+ testStringImport(expected, >+ DotTestGraphs.MULTI_EDGE_STATEMENTS_OVERRIDE); >+ } >+ >+ @Test >+ public void edgeStyleInvis() { >+ Graph graph = dotImport.importDot(DotTestGraphs.EDGE_STYLE_INVIS); >+ assertEquals(2, graph.getNodes().size()); >+ assertEquals(1, graph.getEdges().size()); > } > > @Test >@@ -855,7 +1135,7 @@ > } > > private void testStringImport(Graph expected, String dot) { >- Graph graph = new DotImport().importDot(dot); >+ Graph graph = dotImport.importDot(dot); > Assert.assertNotNull("Resulting graph must not be null", graph); //$NON-NLS-1$ > Assert.assertEquals(expected.toString(), graph.toString()); > } >diff --git a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotInterpreterTests.java b/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotInterpreterTests.java >deleted file mode 100644 >index 11228be..0000000 >--- a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotInterpreterTests.java >+++ /dev/null >@@ -1,366 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2009, 2016 itemis AG and others. >- * >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * Fabian Steeg - initial API and implementation (see bug #277380) >- * Tamas Miklossy (itemis AG) - Add support for all dot attributes (bug #461506) >- * >- *******************************************************************************/ >-package org.eclipse.gef4.dot.tests; >- >-import static org.junit.Assert.assertEquals; >- >-import java.io.StringReader; >-import java.util.ArrayList; >-import java.util.List; >- >-import org.eclipse.gef4.dot.internal.DotAttributes; >-import org.eclipse.gef4.dot.internal.DotImport; >-import org.eclipse.gef4.dot.internal.DotInterpreter; >-import org.eclipse.gef4.dot.internal.parser.DotStandaloneSetup; >-import org.eclipse.gef4.dot.internal.parser.dot.DotAst; >-import org.eclipse.gef4.dot.internal.parser.layout.Layout; >-import org.eclipse.gef4.dot.internal.parser.parser.antlr.DotParser; >-import org.eclipse.gef4.dot.internal.parser.rankdir.Rankdir; >-import org.eclipse.gef4.dot.internal.parser.style.EdgeStyle; >-import org.eclipse.gef4.graph.Edge; >-import org.eclipse.gef4.graph.Graph; >-import org.eclipse.gef4.graph.Node; >-import org.junit.Assert; >-import org.junit.Test; >- >-import com.google.inject.Injector; >- >-/** >- * Tests for dynamic import of DOT to a Zest graph instance. >- * >- * @author Fabian Steeg (fsteeg) >- */ >-public final class DotInterpreterTests { >- >- private static final Injector dotInjector = new DotStandaloneSetup() >- .createInjectorAndDoEMFRegistration(); >- private static final DotParser dotParser = dotInjector >- .getInstance(DotParser.class); >- >- private final DotInterpreter interpreter = new DotInterpreter(); >- >- @Test >- public void digraphType() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.TWO_NODES_ONE_DIRECTED_EDGE)) >- .get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(DotAttributes._TYPE__G__DIGRAPH, >- DotAttributes._getType(graph)); >- } >- >- @Test >- public void graphType() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.TWO_NODES_ONE_EDGE)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(DotAttributes._TYPE__G__GRAPH, >- DotAttributes._getType(graph)); >- } >- >- @Test >- public void nodeDefaultLabel() { >- Graph graph = interpreter.interpret(parse(DotTestGraphs.ONE_NODE)) >- .get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("1", //$NON-NLS-1$ >- DotAttributes._getName(graph.getNodes().get(0))); >- } >- >- @Test >- public void nodeCount() { >- Graph graph = interpreter.interpret(parse(DotTestGraphs.TWO_NODES)) >- .get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(2, graph.getNodes().size()); >- } >- >- @Test >- public void edgeCount() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.TWO_NODES_AND_THREE_EDGES)) >- .get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(3, graph.getEdges().size()); >- } >- >- @Test >- public void nodeLabel() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.NODE_LABEL_LOCAL)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("Node1", //$NON-NLS-1$ >- DotAttributes.getLabel(graph.getNodes().get(0))); >- } >- >- @Test >- public void edgeLabel() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.EDGE_LABEL_LOCAL)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("Edge1", DotAttributes.getLabel(graph.getEdges() //$NON-NLS-1$ >- .get(0))); >- } >- >- @Test >- public void edgeStyle() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.EDGE_STYLE_LOCAL)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(EdgeStyle.DASHED.toString(), >- DotAttributes.getStyle(graph.getEdges().get(0))); >- } >- >- @Test >- public void globalEdgeStyle() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.EDGE_STYLE_GLOBAL)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(EdgeStyle.DASHED.toString(), >- DotAttributes.getStyle(graph.getEdges().get(0))); >- } >- >- @Test >- public void globalEdgeLabel() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.EDGE_LABEL_GLOBAL)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("Edge1", DotAttributes.getLabel(graph.getEdges() //$NON-NLS-1$ >- .get(0))); >- } >- >- @Test >- public void globalNodeLabel() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.NODE_LABEL_GLOBAL)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("Node1", //$NON-NLS-1$ >- DotAttributes.getLabel(graph.getNodes().get(0))); >- } >- >- @Test >- public void layoutSpring() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.GRAPH_LAYOUT_FDP)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(Layout.FDP.toString(), >- DotAttributes.getLayout(graph)); >- } >- >- @Test >- public void layoutGrid() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.GRAPH_LAYOUT_OSAGE)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(Layout.OSAGE.toString(), >- DotAttributes.getLayout(graph)); >- } >- >- @Test >- public void layoutRadial() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.GRAPH_LAYOUT_TWOPI)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(Layout.TWOPI.toString(), >- DotAttributes.getLayout(graph)); >- } >- >- @Test >- public void layoutTree() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.GRAPH_LAYOUT_DOT)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(Layout.DOT.toString(), >- DotAttributes.getLayout(graph)); >- } >- >- @Test >- public void layoutHorizontalTreeViaLayout() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.GRAPH_LAYOUT_DOT_HORIZONTAL)) >- .get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(Layout.DOT.toString(), >- DotAttributes.getLayout(graph)); >- Assert.assertEquals(Rankdir.LR, DotAttributes.getRankdirParsed(graph)); >- } >- >- @Test >- public void layoutHorizontalTreeViaAttribute() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.GRAPH_RANKDIR_LR)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(Rankdir.LR, DotAttributes.getRankdirParsed(graph)); >- } >- >- @Test >- public void globalNodeAttributeAdHocNodes() { >- Graph graph = interpreter >- .interpret( >- parse(DotTestGraphs.GLOBAL_NODE_LABEL_AD_HOC_NODES)) >- .get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("TEXT", //$NON-NLS-1$ >- DotAttributes.getLabel(graph.getNodes().get(0))); >- } >- >- @Test >- public void globalEdgeAttributeAdHocNodes() { >- Graph graph = interpreter >- .interpret( >- parse(DotTestGraphs.GLOBAL_EDGE_LABEL_AD_HOC_NODES)) >- .get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("TEXT", DotAttributes.getLabel(graph.getEdges() //$NON-NLS-1$ >- .get(0))); >- } >- >- @Test >- public void headerCommentGraph() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.HEADER_COMMENT)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(2, graph.getNodes().size()); >- Assert.assertEquals(1, graph.getEdges().size()); >- } >- >- @Test >- public void nodesBeforeEdges() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.NODES_BEFORE_EDGES)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(4, graph.getNodes().size()); >- Assert.assertEquals(3, graph.getEdges().size()); >- } >- >- @Test >- public void nodesAfterEdges() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.NODES_AFTER_EDGES)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(4, graph.getNodes().size()); >- Assert.assertEquals(3, graph.getEdges().size()); >- Assert.assertEquals("node", >- DotAttributes.getLabel(graph.getNodes().get(0))); >- } >- >- @Test >- public void useInterpreterTwice() { >- String dot = DotTestGraphs.NODES_AFTER_EDGES; >- Graph graph = interpreter.interpret(parse(dot)).get(0); >- graph = interpreter.interpret(parse(dot)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(4, graph.getNodes().size()); >- Assert.assertEquals(3, graph.getEdges().size()); >- } >- >- @Test >- public void idsWithQuotes() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.IDS_WITH_QUOTES)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- List<Node> list = graph.getNodes(); >- Assert.assertEquals("node 1", //$NON-NLS-1$ >- DotAttributes._getName(list.get(0))); >- Assert.assertEquals("node 2", //$NON-NLS-1$ >- DotAttributes._getName(list.get(1))); >- } >- >- @Test >- public void escapedQuotes() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.ESCAPED_QUOTES_LABEL)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("node \"1\"", //$NON-NLS-1$ >- DotAttributes.getLabel(graph.getNodes().get(0))); >- } >- >- @Test >- public void fullyQuoted() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.FULLY_QUOTED_IDS)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals(2, graph.getNodes().size()); >- Assert.assertEquals(1, graph.getEdges().size()); >- List<Node> list = graph.getNodes(); >- Assert.assertEquals("n1", //$NON-NLS-1$ >- DotAttributes._getName(list.get(0))); >- Assert.assertEquals("n2", //$NON-NLS-1$ >- DotAttributes._getName(list.get(1))); >- } >- >- @Test >- public void labelsWithQuotes() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.QUOTED_LABELS)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- List<Node> list = graph.getNodes(); >- Assert.assertEquals("node 1", //$NON-NLS-1$ >- DotAttributes.getLabel(list.get(0))); >- Assert.assertEquals("node 2", //$NON-NLS-1$ >- DotAttributes.getLabel(list.get(1))); >- Assert.assertEquals("edge 1", >- DotAttributes.getLabel(graph.getEdges().get(0))); >- } >- >- @Test >- public void newLinesInLabels() { >- Graph graph = interpreter >- .interpret(parse(DotTestGraphs.NEW_LINES_IN_LABELS)).get(0); >- Assert.assertNotNull("Created graph must not be null", graph); //$NON-NLS-1$ >- Assert.assertEquals("node" + System.lineSeparator() + "1", //$NON-NLS-1$ >- DotAttributes.getLabel(graph.getNodes().get(0))); >- } >- >- @Test >- public void multiEdgeStatements() { >- Graph graph = new DotImport() >- .importDot(DotTestGraphs.MULTI_EDGE_STATEMENTS); >- assertEquals(4, graph.getNodes().size()); >- assertEquals(3, graph.getEdges().size()); >- /* Each node should be connected to one other, the previous node: */ >- List<Node> list = graph.getNodes(); >- assertEquals(1, getSourceConnections(list.get(1), graph).size()); >- assertEquals(1, getSourceConnections(list.get(1), graph).size()); >- assertEquals(1, getSourceConnections(list.get(1), graph).size()); >- } >- >- private List<Edge> getSourceConnections(Node node, Graph graph) { >- List<Edge> result = new ArrayList<>(); >- List<Edge> edges = graph.getEdges(); >- for (Edge edge : edges) >- if (edge.getTarget().equals(node)) >- result.add(edge); >- return result; >- } >- >- @Test >- /* see http://www.graphviz.org/doc/info/attrs.html#d:style */ >- public void edgeStyleInvis() { >- Graph graph = new DotImport() >- .importDot(DotTestGraphs.EDGE_STYLE_INVIS); >- assertEquals(2, graph.getNodes().size()); >- assertEquals(1, graph.getEdges().size()); >- } >- >- @Test(expected = IllegalArgumentException.class) >- public void faultyLayout() { >- interpreter.interpret(parse("graph Sample{graph[layout=cool];1;}")); //$NON-NLS-1$ >- } >- >- private DotAst parse(String dot) { >- return (DotAst) dotParser.parse(new StringReader(dot)) >- .getRootASTElement(); >- } >-} >diff --git a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotTestGraphs.xtend b/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotTestGraphs.xtend >index efa6d6a..2ff7a3c 100644 >--- a/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotTestGraphs.xtend >+++ b/org.eclipse.gef4.dot.tests/src/org/eclipse/gef4/dot/tests/DotTestGraphs.xtend >@@ -171,12 +171,28 @@ > } > ''' > >- public static val MULTI_EDGE_STATEMENTS = ''' >+ public static val MULTI_EDGE_STATEMENTS_GLOBAL = ''' > digraph { >+ edge[arrowhead=ornormal] >+ 1->2->3->4 > 1->2->3->4 > } > ''' > >+ public static val MULTI_EDGE_STATEMENTS_LOCAL = ''' >+ digraph { >+ 1->2->3->4[arrowhead=ornormal] >+ 1->2->3->4[arrowhead=olnormal] >+ } >+ ''' >+ >+ public static val MULTI_EDGE_STATEMENTS_OVERRIDE = ''' >+ digraph { >+ edge[arrowhead=olnormal] >+ 1->2->3->4[arrowhead=ornormal] >+ 1->2->3->4 >+ } >+ ''' > public static val NEW_LINES_IN_LABELS = ''' > graph { > n1[label= >diff --git a/org.eclipse.gef4.dot/src/org/eclipse/gef4/dot/internal/DotImport.xtend b/org.eclipse.gef4.dot/src/org/eclipse/gef4/dot/internal/DotImport.xtend >index a7ce587..375185f 100644 >--- a/org.eclipse.gef4.dot/src/org/eclipse/gef4/dot/internal/DotImport.xtend >+++ b/org.eclipse.gef4.dot/src/org/eclipse/gef4/dot/internal/DotImport.xtend >@@ -7,6 +7,7 @@ > * > * Contributors: > * Alexander NyÃen (itemis AG) - initial API and implementation >+ * Tamas Miklossy (itemis AG) - merge DotInterpreter into DotImport (bug #491261) > * > *******************************************************************************/ > package org.eclipse.gef4.dot.internal >@@ -14,10 +15,32 @@ > import com.google.inject.Injector > import java.io.File > import java.io.StringReader >+import java.util.List >+import java.util.Map > import org.eclipse.gef4.dot.internal.parser.DotStandaloneSetup >+import org.eclipse.gef4.dot.internal.parser.conversion.DotTerminalConverters >+import org.eclipse.gef4.dot.internal.parser.dot.AttrList >+import org.eclipse.gef4.dot.internal.parser.dot.AttrStmt >+import org.eclipse.gef4.dot.internal.parser.dot.Attribute > import org.eclipse.gef4.dot.internal.parser.dot.DotAst >+import org.eclipse.gef4.dot.internal.parser.dot.DotGraph >+import org.eclipse.gef4.dot.internal.parser.dot.EdgeRhs >+import org.eclipse.gef4.dot.internal.parser.dot.EdgeRhsNode >+import org.eclipse.gef4.dot.internal.parser.dot.EdgeRhsSubgraph >+import org.eclipse.gef4.dot.internal.parser.dot.EdgeStmtNode >+import org.eclipse.gef4.dot.internal.parser.dot.GraphType >+import org.eclipse.gef4.dot.internal.parser.dot.NodeId >+import org.eclipse.gef4.dot.internal.parser.dot.NodeStmt >+import org.eclipse.gef4.dot.internal.parser.dot.Stmt > import org.eclipse.gef4.dot.internal.parser.parser.antlr.DotParser >+import org.eclipse.gef4.dot.internal.parser.splines.Splines >+import org.eclipse.gef4.graph.Edge > import org.eclipse.gef4.graph.Graph >+import org.eclipse.gef4.graph.Graph.Builder >+import org.eclipse.gef4.graph.Node >+ >+import static extension org.eclipse.gef4.dot.internal.DotAttributes.* >+import org.eclipse.gef4.dot.internal.parser.dot.DotFactory > > /** > * A parser that creates a {@link Graph} with {@link DotAttributes} from a Graphviz DOT string or file. >@@ -27,9 +50,15 @@ > */ > class DotImport { > >- private static final Injector dotInjector = new DotStandaloneSetup().createInjectorAndDoEMFRegistration(); >- private static final DotParser dotParser = dotInjector.getInstance(typeof(DotParser)) as DotParser; >- >+ // fields are private by default >+ val static Injector dotInjector = new DotStandaloneSetup().createInjectorAndDoEMFRegistration >+ val static DotParser dotParser = dotInjector.getInstance(DotParser) >+ >+ Builder graphBuilder >+ Map<String, String> globalGraphAttributes = newHashMap >+ Map<String, String> globalNodeAttributes = newHashMap >+ Map<String, String> globalEdgeAttributes = newHashMap >+ > // TODO: support a list of graphs > def Graph importDot(String dotString) { > var parseResult = dotParser.parse(new StringReader(dotString)) >@@ -41,12 +70,280 @@ > } > // TODO: use validator to semantically validate as well > >- // TODO: return list of graphs rather than first one >- new DotInterpreter().interpret(parseResult.rootASTElement as DotAst).head >+ // TODO: return list of graphs rather than only the first one >+ (parseResult.rootASTElement as DotAst).transformDotAst > } > > // TODO: support a list of graphs > def Graph importDot(File dotFile) { > importDot(DotFileUtils.read(dotFile)) > } >+ >+ private def Graph transformDotAst(DotAst it){ >+ // TODO: return list of graphs rather than only the first one >+ graphs.map[transformDotGraph].head >+ } >+ >+ private def Graph transformDotGraph(DotGraph it){ >+ // clear global attributes, which only hold for each respective graph >+ globalGraphAttributes.clear >+ globalNodeAttributes.clear >+ globalEdgeAttributes.clear >+ >+ // create a new graph builder and clear the nodes map >+ graphBuilder = new Graph.Builder >+ _createCache_createNode.clear >+ >+ // name (meta-attribute) >+ val escapedName = name.escaped >+ if (escapedName != null) { >+ graphBuilder.attr(_NAME__GNE, escapedName) >+ } >+ >+ // type (meta-attribute) >+ graphBuilder.attr(_TYPE__G, >+ if (type == GraphType.GRAPH) >+ _TYPE__G__GRAPH >+ else >+ _TYPE__G__DIGRAPH >+ ) >+ >+ // process all statements except for graph attributes, they will be processed later >+ stmts.filter[!(it instanceof Attribute)].forEach[transformStmt] >+ >+ // process the graph last, so we can initialize attributes of the >+ // created graph object rather than using the builder we can thus >+ // ensure attribute values get properly validated. >+ val graph = graphBuilder.build >+ >+ val setter = [ >+ String attributeName, (Graph, String)=>void f | >+ val attributeValue = getAttributeValue(attributeName) >+ if (attributeValue != null) { >+ f.apply(graph, attributeValue) >+ } else if (globalGraphAttributes.containsKey(attributeName)) { >+ f.apply(graph, globalGraphAttributes.get(attributeName)) >+ } >+ ] >+ >+ setter.apply(LAYOUT__G, [g, value | g.setLayout(value) ]) >+ setter.apply(RANKDIR__G, [g, value | g.setRankdir(value)]) >+ >+ // splines >+ var splines = getAttributeValue(SPLINES__G) >+ if (splines == null && globalGraphAttributes.containsKey(SPLINES__G)) { >+ splines = globalGraphAttributes.get(SPLINES__G) >+ } >+ if (splines != null) { >+ // XXX: splines can either be a defined enum value or a bool value >+ // (which is mapped to respective enum values) we use the enum >+ // values alone and thus map the bool value here >+ val Boolean booleanValue = DotLanguageSupport.parseAttributeValue( >+ DotLanguageSupport.BOOL_PARSER, splines) >+ if (booleanValue != null) { >+ graph.setSplinesParsed( >+ if (Boolean.TRUE.equals(booleanValue)) >+ Splines.TRUE >+ else >+ Splines.FALSE >+ ) >+ } else { >+ graph.setSplines(splines) >+ } >+ } >+ >+ graph >+ } >+ >+ private def Node transformNodeId(NodeId it) { >+ // create an empty attribute lists indicating no local node attribute definitions >+ transformNodeId(#[DotFactory.eINSTANCE.createAttrList]) >+ } >+ >+ private def Node transformNodeId(NodeId it, List<AttrList> attrLists) { >+ val node = name.escaped.createNode >+ >+ val setter = [ >+ String attributeName, (Node, String)=>void f | >+ val attributeValue = attrLists.getAttributeValue(attributeName) >+ if (attributeValue != null) { >+ f.apply(node, attributeValue) >+ } else if (globalNodeAttributes.containsKey(attributeName)) { >+ f.apply(node, globalNodeAttributes.get(attributeName)) >+ } >+ ] >+ >+ setter.apply(DISTORTION__N, [n, value | n.setDistortion(value)]) >+ setter.apply(FIXEDSIZE__N, [n, value | n.setFixedSize(value) ]) >+ setter.apply(HEIGHT__N, [n, value | n.setHeight(value) ]) >+ setter.apply(ID__GNE, [n, value | n.setId(value) ]) >+ setter.apply(LABEL__GNE, [n, value | n.setLabel(value) ]) >+ setter.apply(POS__NE, [n, value | n.setPos(value) ]) >+ setter.apply(SHAPE__N, [n, value | n.setShape(value) ]) >+ setter.apply(SIDES__N, [n, value | n.setSides(value) ]) >+ setter.apply(SKEW__N, [n, value | n.setSkew(value) ]) >+ setter.apply(STYLE__GNE, [n, value | n.setStyle(value) ]) >+ setter.apply(WIDTH__N, [n, value | n.setWidth(value) ]) >+ setter.apply(XLABEL__NE, [n, value | n.setXLabel(value) ]) >+ setter.apply(XLP__NE, [n, value | n.setXlp(value) ]) >+ >+ node >+ } >+ >+ /* >+ ******************************************************************************************************************************** >+ * dynamic dispatch methods >+ ******************************************************************************************************************************** >+ */ >+ private def dispatch void transformStmt(Stmt it){ >+ throw new IllegalArgumentException("DotImport cannot transform statement: " + class) >+ } >+ >+ private def dispatch void transformStmt(AttrStmt it) { >+ switch type { >+ case GRAPH: { >+ // global graph attributes >+ attrLists.forEach[ >+ attributes.forEach[ >+ globalGraphAttributes.put(name, value.escaped) >+ ] >+ ] >+ } >+ case NODE: { >+ // global node attributes >+ attrLists.forEach[ >+ attributes.forEach[ >+ globalNodeAttributes.put(name, value.escaped) >+ ] >+ ] >+ } >+ case EDGE: { >+ // global edge attributes >+ attrLists.forEach[ >+ attributes.forEach[ >+ globalEdgeAttributes.put(name, value.escaped) >+ ] >+ ] >+ } >+ } >+ } >+ >+ private def dispatch void transformStmt(NodeStmt it){ >+ node.transformNodeId(attrLists) >+ } >+ >+ private def dispatch void transformStmt(EdgeStmtNode it) { >+ var sourceNode = node.transformNodeId >+ for(EdgeRhs edgeRhs : edgeRHS){ >+ switch edgeRhs { >+ EdgeRhsNode: { >+ val targetNode = edgeRhs.node.transformNodeId >+ createEdge(sourceNode, edgeRhs.op.literal, targetNode, attrLists) >+ // current target node may be source for next EdgeRHS >+ sourceNode = targetNode >+ } >+ EdgeRhsSubgraph: { >+ // TODO: add support for transforming edges with >+ // subgraphs on their right hand side >+ } >+ default:{ >+ throw new IllegalArgumentException("DotImport cannot transform EdgeRhs: " + class) >+ } >+ } >+ } >+ } >+ >+ private def create new Node.Builder().buildNode() createNode(String nodeName) { >+ _setName(nodeName) >+ graphBuilder.nodes(it) >+ } >+ >+ def private void createEdge(Node sourceNode, String edgeOp, Node targetNode, List<AttrList> attrLists) { >+ val edge = new Edge.Builder(sourceNode, targetNode) >+ .attr(_NAME__GNE, sourceNode._getName + edgeOp + targetNode._getName) >+ .buildEdge() >+ >+ val setter = [ >+ String attributeName, (Edge, String)=>void f | >+ val attributeValue = attrLists.getAttributeValue(attributeName) >+ if (attributeValue != null) { >+ f.apply(edge, attributeValue) >+ } else if (globalEdgeAttributes.containsKey(attributeName)) { >+ f.apply(edge, globalEdgeAttributes.get(attributeName)) >+ } >+ ] >+ >+ setter.apply(ARROWHEAD__E, [e, value | e.setArrowHead(value)]) >+ setter.apply(ARROWSIZE__E, [e, value | e.setArrowSize(value)]) >+ setter.apply(ARROWTAIL__E, [e, value | e.setArrowTail(value)]) >+ setter.apply(DIR__E, [e, value | e.setDir(value) ]) >+ setter.apply(HEAD_LP__E, [e, value | e.setHeadLp(value) ]) >+ setter.apply(HEADLABEL__E, [e, value | e.setHeadLabel(value)]) >+ setter.apply(ID__GNE, [e, value | e.setId(value) ]) >+ setter.apply(LABEL__GNE, [e, value | e.setLabel(value) ]) >+ setter.apply(LP__GE, [e, value | e.setLp(value) ]) >+ setter.apply(POS__NE, [e, value | e.setPos(value) ]) >+ setter.apply(STYLE__GNE, [e, value | e.setStyle(value) ]) >+ setter.apply(TAILLABEL__E, [e, value | e.setTailLabel(value)]) >+ setter.apply(TAIL_LP__E, [e, value | e.setTailLp(value) ]) >+ setter.apply(XLABEL__NE, [e, value | e.setXLabel(value) ]) >+ setter.apply(XLP__NE, [e, value | e.setXlp(value) ]) >+ >+ graphBuilder.edges(edge) >+ } >+ >+ def private String getAttributeValue(DotGraph graph, String name) { >+ for (stmt : graph.stmts) { >+ var String value = >+ switch stmt { >+ AttrStmt: stmt.getAttributeValue(name) >+ Attribute: stmt.getAttributeValue(name) >+ } >+ if (value != null) { >+ return value >+ } >+ } >+ null >+ } >+ >+ /** >+ * Returns the value of the first attribute with the give name or >+ * <code>null</code> if no attribute could be found. >+ * >+ * @param attrLists >+ * The {@link AttrList}s to search. >+ * @param name >+ * The name of the attribute whose value is to be retrieved. >+ * @return The attribute value or <code>null</code> in case the attribute >+ * could not be found. >+ */ >+ def private String getAttributeValue(List<AttrList> attrLists, String name) { >+ for (AttrList attrList : attrLists) { >+ val value = attrList.getAttributeValue(name) >+ if (value != null) { >+ return value >+ } >+ } >+ null >+ } >+ >+ def private String getAttributeValue(AttrStmt attrStmt, String name) { >+ attrStmt.attrLists.getAttributeValue(name) >+ } >+ >+ def private String getAttributeValue(AttrList attrList, String name) { >+ attrList.attributes.findFirst[it.name==name]?.value.escaped >+ } >+ >+ def private String getAttributeValue(Attribute attribute, String name) { >+ if (attribute.name.equals(name)) { >+ return attribute.value.escaped >+ } >+ null >+ } >+ >+ private def escaped(String it) { >+ DotTerminalConverters.unquote(it) >+ } >+ > } >diff --git a/org.eclipse.gef4.dot/src/org/eclipse/gef4/dot/internal/DotInterpreter.java b/org.eclipse.gef4.dot/src/org/eclipse/gef4/dot/internal/DotInterpreter.java >deleted file mode 100644 >index 67b9ba1..0000000 >--- a/org.eclipse.gef4.dot/src/org/eclipse/gef4/dot/internal/DotInterpreter.java >+++ /dev/null >@@ -1,600 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2009, 2016 Fabian Steeg and others. >- * >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * Fabian Steeg - initial API and implementation (bug #277380) >- * Alexander NyÃen (itemis AG) - several refactorings and additions (bugs #487081, #489793) >- * Tamas Miklossy (itemis AG) - support for arrowType edge decorations (bug #477980) >- * - support for polygon-based node shapes (bug #441352) >- * >- *******************************************************************************/ >- >-package org.eclipse.gef4.dot.internal; >- >-import java.util.ArrayList; >-import java.util.HashMap; >-import java.util.Iterator; >-import java.util.List; >-import java.util.Map; >- >-import org.eclipse.emf.common.util.TreeIterator; >-import org.eclipse.emf.ecore.EObject; >-import org.eclipse.emf.ecore.util.EcoreUtil; >-import org.eclipse.gef4.dot.internal.parser.conversion.DotTerminalConverters; >-import org.eclipse.gef4.dot.internal.parser.dot.AttrList; >-import org.eclipse.gef4.dot.internal.parser.dot.AttrStmt; >-import org.eclipse.gef4.dot.internal.parser.dot.Attribute; >-import org.eclipse.gef4.dot.internal.parser.dot.AttributeType; >-import org.eclipse.gef4.dot.internal.parser.dot.DotAst; >-import org.eclipse.gef4.dot.internal.parser.dot.DotGraph; >-import org.eclipse.gef4.dot.internal.parser.dot.EdgeRhsNode; >-import org.eclipse.gef4.dot.internal.parser.dot.EdgeStmtNode; >-import org.eclipse.gef4.dot.internal.parser.dot.GraphType; >-import org.eclipse.gef4.dot.internal.parser.dot.NodeId; >-import org.eclipse.gef4.dot.internal.parser.dot.NodeStmt; >-import org.eclipse.gef4.dot.internal.parser.dot.Stmt; >-import org.eclipse.gef4.dot.internal.parser.dot.util.DotSwitch; >-import org.eclipse.gef4.dot.internal.parser.splines.Splines; >-import org.eclipse.gef4.graph.Edge; >-import org.eclipse.gef4.graph.Graph; >-import org.eclipse.gef4.graph.Graph.Builder; >-import org.eclipse.gef4.graph.Node; >- >-/** >- * Create a {@link Graph} instance from a DOT string by interpreting the AST of >- * the parsed DOT. >- * >- * @author Fabian Steeg (fsteeg) >- * @author Alexander NyÃen (anyssen) >- */ >-// TODO: merge this into DotImport; turning DotImport into an Xtend class (so we >-// can use create functions) >-public final class DotInterpreter extends DotSwitch<Object> { >- >- private Builder graphBuilder; >- private Map<String, Node> nodesByName = new HashMap<>(); >- >- private Map<String, String> globalGraphAttributes = new HashMap<>(); >- private Map<String, String> globalNodeAttributes = new HashMap<>(); >- private Map<String, String> globalEdgeAttributes = new HashMap<>(); >- >- private boolean createEdge; >- private String currentArrowHead; >- private String currentArrowTail; >- private String currentArrowSize; >- private String currentEdgeDirection; >- private String currentEdgeStyle; >- private String currentEdgeLabel; >- private String currentEdgeSourceNodeName; >- private String currentEdgePos; >- private String currentEdgeXLabel; >- private String currentEdgeXlp; >- private String currentEdgeLp; >- private String currentEdgeTailLabel; >- private String currentEdgeHeadLabel; >- private String currentEdgeHeadLp; >- private String currentEdgeTailLp; >- private String currentEdgeId; >- private String currentEdgeOp; >- >- /** >- * @param dotAst >- * The DOT abstract syntax tree (AST) to interpret >- * @return A graph instance for the given DOT AST >- */ >- public List<Graph> interpret(DotAst dotAst) { >- List<Graph> graphs = new ArrayList<>(); >- for (DotGraph dotGraph : dotAst.getGraphs()) { >- // clear global attributes, which only hold for each respective >- // graph >- globalGraphAttributes.clear(); >- globalNodeAttributes.clear(); >- globalEdgeAttributes.clear(); >- >- // create a new graph builder and clear the nodes map >- graphBuilder = new Graph.Builder(); >- nodesByName.clear(); >- >- // process all contents (nodes, edges, attributes) >- TreeIterator<Object> contents = EcoreUtil >- .getAllProperContents(dotGraph, false); >- while (contents.hasNext()) { >- doSwitch((EObject) contents.next()); >- } >- >- // process the graph last, so we can initialize attributes of the >- // created graph object rather than using the builder; we can thus >- // ensure attribute values get properly validated. >- Graph g = (Graph) doSwitch(dotGraph); >- if (g != null) { >- graphs.add(g); >- } >- } >- return graphs; >- } >- >- @Override >- public Object caseDotGraph(DotGraph dotGraph) { >- // name (meta-attribute) >- String name = escaped(dotGraph.getName()); >- if (name != null) { >- graphBuilder.attr(DotAttributes._NAME__GNE, name); >- } >- >- // type (meta-attribute) >- GraphType graphType = dotGraph.getType(); >- graphBuilder.attr(DotAttributes._TYPE__G, >- GraphType.GRAPH.equals(graphType) >- ? DotAttributes._TYPE__G__GRAPH >- : DotAttributes._TYPE__G__DIGRAPH); >- Graph graph = graphBuilder.build(); >- >- // layout >- String layout = getAttributeValue(dotGraph, DotAttributes.LAYOUT__G); >- if (layout != null) { >- DotAttributes.setLayout(graph, layout); >- } else if (globalGraphAttributes.containsKey(DotAttributes.LAYOUT__G)) { >- DotAttributes.setLayout(graph, >- globalGraphAttributes.get(DotAttributes.LAYOUT__G)); >- } >- // rankdir >- String rankdir = getAttributeValue(dotGraph, DotAttributes.RANKDIR__G); >- if (rankdir != null) { >- DotAttributes.setRankdir(graph, rankdir); >- } else if (globalGraphAttributes >- .containsKey(DotAttributes.RANKDIR__G)) { >- DotAttributes.setRankdir(graph, >- globalGraphAttributes.get(DotAttributes.RANKDIR__G)); >- } >- // splines >- String splines = getAttributeValue(dotGraph, DotAttributes.SPLINES__G); >- if (splines == null && globalGraphAttributes >- .containsKey(DotAttributes.SPLINES__G)) { >- splines = globalGraphAttributes.get(DotAttributes.SPLINES__G); >- } >- if (splines != null) { >- // XXX: splines can either be a defined enum value or a bool value >- // (which is mapped to respective enum values); we use the enum >- // values alone and thus map the bool value here >- Boolean booleanValue = DotLanguageSupport.parseAttributeValue( >- DotLanguageSupport.BOOL_PARSER, splines); >- if (booleanValue != null) { >- DotAttributes.setSplinesParsed(graph, >- Boolean.TRUE.equals(booleanValue) ? Splines.TRUE >- : Splines.FALSE); >- } else { >- DotAttributes.setSplines(graph, splines); >- } >- } >- return graph; >- } >- >- @Override >- public Object caseAttrStmt(AttrStmt attrStmt) { >- AttributeType type = attrStmt.getType(); >- switch (type) { >- case EDGE: { >- // global edge attributes >- for (AttrList al : attrStmt.getAttrLists()) { >- for (Attribute a : al.getAttributes()) { >- globalEdgeAttributes.put(a.getName(), >- escaped(a.getValue())); >- } >- } >- break; >- } >- case NODE: { >- // global node attributes >- for (AttrList al : attrStmt.getAttrLists()) { >- for (Attribute a : al.getAttributes()) { >- globalNodeAttributes.put(a.getName(), >- escaped(a.getValue())); >- } >- } >- break; >- } >- case GRAPH: { >- // global graph attributes >- for (AttrList al : attrStmt.getAttrLists()) { >- for (Attribute a : al.getAttributes()) { >- globalGraphAttributes.put(a.getName(), >- escaped(a.getValue())); >- } >- } >- break; >- } >- } >- return super.caseAttrStmt(attrStmt); >- } >- >- @Override >- public Object caseNodeStmt(NodeStmt nodeStmt) { >- // name (from grammar definition, not attribute) >- Node node = node(escaped(nodeStmt.getNode().getName())); >- >- // distortion >- String distortion = getAttributeValue(nodeStmt, >- DotAttributes.DISTORTION__N); >- if (distortion != null) { >- DotAttributes.setDistortion(node, distortion); >- } >- >- // id >- String id = getAttributeValue(nodeStmt, DotAttributes.ID__GNE); >- if (id != null) { >- DotAttributes.setId(node, id); >- } >- >- // label >- String label = getAttributeValue(nodeStmt, DotAttributes.LABEL__GNE); >- if (label != null) { >- DotAttributes.setLabel(node, label); >- } >- >- // xlabel >- String xLabel = getAttributeValue(nodeStmt, DotAttributes.XLABEL__NE); >- if (xLabel != null) { >- DotAttributes.setXLabel(node, xLabel); >- } >- >- // pos >- String pos = getAttributeValue(nodeStmt, DotAttributes.POS__NE); >- if (pos != null) { >- DotAttributes.setPos(node, pos); >- } >- >- // xlp >- String xlp = getAttributeValue(nodeStmt, DotAttributes.XLP__NE); >- if (xlp != null) { >- DotAttributes.setXlp(node, xlp); >- } >- >- // width >- String width = getAttributeValue(nodeStmt, DotAttributes.WIDTH__N); >- if (width != null) { >- DotAttributes.setWidth(node, width); >- } >- >- // height >- String height = getAttributeValue(nodeStmt, DotAttributes.HEIGHT__N); >- if (height != null) { >- DotAttributes.setHeight(node, height); >- } >- >- // fixedsize >- String fixedSize = getAttributeValue(nodeStmt, >- DotAttributes.FIXEDSIZE__N); >- if (fixedSize != null) { >- DotAttributes.setFixedSize(node, fixedSize); >- } >- >- // shape >- String shape = getAttributeValue(nodeStmt, DotAttributes.SHAPE__N); >- if (shape != null) { >- DotAttributes.setShape(node, shape); >- } >- >- // sides >- String sides = getAttributeValue(nodeStmt, DotAttributes.SIDES__N); >- if (sides != null) { >- DotAttributes.setSides(node, sides); >- } >- >- // skew >- String skew = getAttributeValue(nodeStmt, DotAttributes.SKEW__N); >- if (skew != null) { >- DotAttributes.setSkew(node, skew); >- } >- >- // style >- String style = getAttributeValue(nodeStmt, DotAttributes.STYLE__GNE); >- if (style != null) { >- DotAttributes.setStyle(node, style); >- } >- return super.caseNodeStmt(nodeStmt); >- } >- >- @Override >- public Object caseEdgeStmtNode(EdgeStmtNode object) { >- currentEdgeId = getAttributeValue(object, DotAttributes.ID__GNE); >- currentEdgeLabel = getAttributeValue(object, DotAttributes.LABEL__GNE); >- currentEdgeLp = getAttributeValue(object, DotAttributes.LP__GE); >- currentEdgeXLabel = getAttributeValue(object, DotAttributes.XLABEL__NE); >- currentEdgeXlp = getAttributeValue(object, DotAttributes.XLP__NE); >- currentEdgeStyle = getAttributeValue(object, DotAttributes.STYLE__GNE); >- currentEdgePos = getAttributeValue(object, DotAttributes.POS__NE); >- currentEdgeHeadLabel = getAttributeValue(object, >- DotAttributes.HEADLABEL__E); >- currentEdgeHeadLp = getAttributeValue(object, DotAttributes.HEAD_LP__E); >- currentEdgeTailLabel = getAttributeValue(object, >- DotAttributes.TAILLABEL__E); >- currentEdgeTailLp = getAttributeValue(object, DotAttributes.TAIL_LP__E); >- currentArrowHead = getAttributeValue(object, >- DotAttributes.ARROWHEAD__E); >- currentArrowTail = getAttributeValue(object, >- DotAttributes.ARROWTAIL__E); >- currentArrowSize = getAttributeValue(object, >- DotAttributes.ARROWSIZE__E); >- currentEdgeDirection = getAttributeValue(object, DotAttributes.DIR__E); >- return super.caseEdgeStmtNode(object); >- } >- >- @Override >- public Object caseNodeId(NodeId object) { >- if (!createEdge) { >- currentEdgeSourceNodeName = escaped(object.getName()); >- } else { >- String targetNodeName = escaped(object.getName()); >- if (currentEdgeSourceNodeName != null && targetNodeName != null) { >- edge(currentEdgeSourceNodeName, currentEdgeOp, targetNodeName); >- // current target node may be source for next EdgeRHS >- currentEdgeSourceNodeName = targetNodeName; >- } >- createEdge = false; >- } >- return super.caseNodeId(object); >- } >- >- private void edge(String sourceNodeName, String edgeOp, >- String targetNodeName) { >- Edge edge = new Edge.Builder(node(sourceNodeName), node(targetNodeName)) >- .attr(DotAttributes._NAME__GNE, >- sourceNodeName + edgeOp + targetNodeName) >- .buildEdge(); >- >- // id >- if (currentEdgeId != null) { >- DotAttributes.setId(edge, currentEdgeId); >- } >- >- // label >- if (currentEdgeLabel != null) { >- DotAttributes.setLabel(edge, currentEdgeLabel); >- } else if (globalEdgeAttributes.containsKey(DotAttributes.LABEL__GNE)) { >- DotAttributes.setLabel(edge, >- globalEdgeAttributes.get(DotAttributes.LABEL__GNE)); >- } >- >- // external label (xlabel) >- if (currentEdgeXLabel != null) { >- DotAttributes.setXLabel(edge, currentEdgeXLabel); >- } else if (globalEdgeAttributes.containsKey(DotAttributes.XLABEL__NE)) { >- DotAttributes.setXLabel(edge, >- globalEdgeAttributes.get(DotAttributes.XLABEL__NE)); >- } >- >- // head label (headllabel) >- if (currentEdgeHeadLabel != null) { >- DotAttributes.setHeadLabel(edge, currentEdgeHeadLabel); >- } else if (globalEdgeAttributes >- .containsKey(DotAttributes.HEADLABEL__E)) { >- DotAttributes.setHeadLabel(edge, >- globalEdgeAttributes.get(DotAttributes.HEADLABEL__E)); >- } >- >- // tail label (taillabel) >- if (currentEdgeTailLabel != null) { >- DotAttributes.setTailLabel(edge, currentEdgeTailLabel); >- } else if (globalEdgeAttributes >- .containsKey(DotAttributes.TAILLABEL__E)) { >- DotAttributes.setTailLabel(edge, >- globalEdgeAttributes.get(DotAttributes.TAILLABEL__E)); >- } >- >- // style >- if (currentEdgeStyle != null) { >- DotAttributes.setStyle(edge, currentEdgeStyle); >- } else if (globalEdgeAttributes.containsKey(DotAttributes.STYLE__GNE)) { >- DotAttributes.setStyle(edge, >- globalEdgeAttributes.get(DotAttributes.STYLE__GNE)); >- } >- >- // arrow head >- if (currentArrowHead != null) { >- DotAttributes.setArrowHead(edge, currentArrowHead); >- } else if (globalEdgeAttributes >- .containsKey(DotAttributes.ARROWHEAD__E)) { >- DotAttributes.setArrowHead(edge, >- globalEdgeAttributes.get(DotAttributes.ARROWHEAD__E)); >- } >- >- // arrow tail >- if (currentArrowTail != null) { >- DotAttributes.setArrowTail(edge, currentArrowTail); >- } else if (globalEdgeAttributes >- .containsKey(DotAttributes.ARROWTAIL__E)) { >- DotAttributes.setArrowTail(edge, >- globalEdgeAttributes.get(DotAttributes.ARROWTAIL__E)); >- } >- >- // arrow size >- if (currentArrowSize != null) { >- DotAttributes.setArrowSize(edge, currentArrowSize); >- } else if (globalEdgeAttributes >- .containsKey(DotAttributes.ARROWSIZE__E)) { >- DotAttributes.setArrowSize(edge, >- globalEdgeAttributes.get(DotAttributes.ARROWSIZE__E)); >- } >- >- // direction >- if (currentEdgeDirection != null) { >- DotAttributes.setDir(edge, currentEdgeDirection); >- } else if (globalEdgeAttributes.containsKey(DotAttributes.DIR__E)) { >- DotAttributes.setDir(edge, >- globalEdgeAttributes.get(DotAttributes.DIR__E)); >- } >- >- // position (pos) >- if (currentEdgePos != null) { >- DotAttributes.setPos(edge, currentEdgePos); >- } >- // label position (lp) >- if (currentEdgeLp != null) { >- DotAttributes.setLp(edge, currentEdgeLp); >- } >- >- // external label position (xlp) >- if (currentEdgeXlp != null) { >- DotAttributes.setXlp(edge, currentEdgeXlp); >- } >- >- // head label position (head_lp) >- if (currentEdgeHeadLp != null) { >- DotAttributes.setHeadLp(edge, currentEdgeHeadLp); >- } >- >- // tail label position (tail_lp) >- if (currentEdgeTailLp != null) { >- DotAttributes.setTailLp(edge, currentEdgeTailLp); >- } >- >- graphBuilder.edges(edge); >- } >- >- @Override >- public Object caseEdgeRhsNode(EdgeRhsNode object) { >- // Set the flag for the node_id case handled above >- createEdge = true; >- currentEdgeOp = object.getOp().getLiteral(); >- return super.caseEdgeRhsNode(object); >- } >- >- private Node node(String nodeName) { >- if (!nodesByName.containsKey(nodeName)) { >- Node node = new Node.Builder() >- .attr(DotAttributes._NAME__GNE, nodeName).buildNode(); >- graphBuilder.nodes(node); >- nodesByName.put(nodeName, node); >- >- // evaluate global attributes >- if (globalNodeAttributes.containsKey(DotAttributes.LABEL__GNE)) { >- DotAttributes.setLabel(node, >- globalNodeAttributes.get(DotAttributes.LABEL__GNE)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.XLABEL__NE)) { >- DotAttributes.setXLabel(node, >- globalNodeAttributes.get(DotAttributes.XLABEL__NE)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.WIDTH__N)) { >- DotAttributes.setWidth(node, >- globalNodeAttributes.get(DotAttributes.WIDTH__N)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.HEIGHT__N)) { >- DotAttributes.setHeight(node, >- globalNodeAttributes.get(DotAttributes.HEIGHT__N)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.FIXEDSIZE__N)) { >- DotAttributes.setFixedSize(node, >- globalNodeAttributes.get(DotAttributes.FIXEDSIZE__N)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.DISTORTION__N)) { >- DotAttributes.setDistortion(node, >- globalNodeAttributes.get(DotAttributes.DISTORTION__N)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.SHAPE__N)) { >- DotAttributes.setShape(node, >- globalNodeAttributes.get(DotAttributes.SHAPE__N)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.SIDES__N)) { >- DotAttributes.setSides(node, >- globalNodeAttributes.get(DotAttributes.SIDES__N)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.SKEW__N)) { >- DotAttributes.setSkew(node, >- globalNodeAttributes.get(DotAttributes.SKEW__N)); >- } >- if (globalNodeAttributes.containsKey(DotAttributes.STYLE__GNE)) { >- DotAttributes.setStyle(node, >- globalNodeAttributes.get(DotAttributes.STYLE__GNE)); >- } >- } >- return nodesByName.get(nodeName); >- } >- >- private String getAttributeValue(final DotGraph graph, final String name) { >- for (Stmt stmt : graph.getStmts()) { >- String value = null; >- if (stmt instanceof AttrStmt) { >- value = getAttributeValue((AttrStmt) stmt, name); >- } else if (stmt instanceof Attribute) { >- value = getAttributeValue((Attribute) stmt, name); >- } >- if (value != null) { >- return value; >- } >- } >- return null; >- } >- >- /** >- * @param stmt >- * The {@link NodeStmt} object, e.g. the object corresponding to >- * "node[label="hi"]" >- * @param name >- * The name of the attribute to get the value for, e.g. "label" >- * @return The value of the given attribute, e.g. "hi" >- */ >- private String getAttributeValue(final NodeStmt stmt, final String name) { >- return getAttributeValue(stmt.getAttrLists(), name); >- } >- >- /** >- * Returns the value of the first attribute with the give name or >- * <code>null</code> if no attribute could be found. >- * >- * @param attrLists >- * The {@link AttrList}s to search. >- * @param name >- * The name of the attribute whose value is to be retrieved. >- * @return The attribute value or <code>null</code> in case the attribute >- * could not be found. >- */ >- private String getAttributeValue(List<AttrList> attrLists, >- final String name) { >- for (AttrList attrList : attrLists) { >- String value = getAttributeValue(attrList, name); >- if (value != null) { >- return value; >- } >- } >- return null; >- } >- >- private String getAttributeValue(AttrStmt attrStmt, String name) { >- return getAttributeValue(attrStmt.getAttrLists(), name); >- } >- >- private String getAttributeValue(EdgeStmtNode edgeStmtNode, String name) { >- return getAttributeValue(edgeStmtNode.getAttrLists(), name); >- } >- >- private String getAttributeValue(AttrList attrList, final String name) { >- Iterator<EObject> attributeContents = attrList.eContents().iterator(); >- while (attributeContents.hasNext()) { >- EObject next = attributeContents.next(); >- if (next instanceof Attribute) { >- String value = getAttributeValue((Attribute) next, name); >- if (value != null) { >- return value; >- } >- } >- } >- return null; >- } >- >- private String getAttributeValue(Attribute attribute, final String name) { >- if (attribute.getName().equals(name)) { >- return escaped(attribute.getValue()); >- } >- return null; >- } >- >- private String escaped(String id) { >- return DotTerminalConverters.unquote(id); >- } >-} >\ No newline at end of file
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 491261
: 263263