blob: 0b1d9a27e65c5f4931faa1903510372e03dc8419 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.vcs.log.graph.parser;
import com.intellij.openapi.util.Pair;
import com.intellij.util.containers.MultiMap;
import com.intellij.vcs.log.graph.api.LinearGraphWithElementInfo;
import com.intellij.vcs.log.graph.api.elements.GraphEdge;
import com.intellij.vcs.log.graph.api.elements.GraphNode;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import static com.intellij.vcs.log.graph.parser.CommitParser.nextSeparatorIndex;
import static com.intellij.vcs.log.graph.parser.CommitParser.toLines;
public class LinearGraphWithElementsInfoParser {
public static LinearGraphWithElementInfo parse(@NotNull String in) {
List<GraphNode> graphNodes = new ArrayList<GraphNode>();
MultiMap<Integer, GraphEdge> upEdges = MultiMap.create();
MultiMap<Integer, GraphEdge> downEdges = MultiMap.create();
for (String line : toLines(in)) {
Pair<GraphNode, List<GraphEdge>> pair = parseLine(line);
assert pair.first.getNodeIndex() == graphNodes.size();
graphNodes.add(pair.first);
for (GraphEdge graphEdge : pair.second) {
upEdges.putValue(graphEdge.getDownNodeIndex(), graphEdge);
downEdges.putValue(graphEdge.getUpNodeIndex(), graphEdge);
}
}
return new TestLinearGraphWithElementsInfo(graphNodes, upEdges, downEdges);
}
/**
* Example input line:
* 0_U|-1_U 2_H
*/
public static Pair<GraphNode, List<GraphEdge>> parseLine(@NotNull String line) {
int separatorIndex = nextSeparatorIndex(line, 0);
Pair<Integer, Character> pair = parseNumberWithChar(line.substring(0, separatorIndex));
GraphNode graphNode = new GraphNode(pair.first, parseGraphNodeType(pair.second));
List<GraphEdge> edges = new ArrayList<GraphEdge>();
for (String edge : line.substring(separatorIndex + 2).split("\\s")) {
if (!edge.isEmpty()) {
pair = parseNumberWithChar(edge);
edges.add(new GraphEdge(graphNode.getNodeIndex(), pair.first, parseGraphEdgeType(pair.second)));
}
}
return new Pair<GraphNode, List<GraphEdge>>(graphNode, edges);
}
public static GraphNode.Type parseGraphNodeType(char c) {
if (c == 'U')
return GraphNode.Type.USUAL;
throw new IllegalStateException("Illegal char for graph node type: " + c);
}
public static GraphEdge.Type parseGraphEdgeType(char c) {
if (c == 'U')
return GraphEdge.Type.USUAL;
if (c == 'H')
return GraphEdge.Type.HIDE;
throw new IllegalStateException("Illegal char for graph edge type: " + c);
}
private static Pair<Integer, Character> parseNumberWithChar(@NotNull String in) {
return new Pair<Integer, Character>(Integer.decode(in.substring(0, in.length() - 2)), in.charAt(in.length() - 1));
}
private static class TestLinearGraphWithElementsInfo implements LinearGraphWithElementInfo {
private final List<GraphNode> myGraphNodes;
private final MultiMap<Integer, GraphEdge> myUpEdges;
private final MultiMap<Integer, GraphEdge> myDownEdges;
private TestLinearGraphWithElementsInfo(List<GraphNode> graphNodes,
MultiMap<Integer, GraphEdge> upEdges,
MultiMap<Integer, GraphEdge> downEdges) {
myGraphNodes = graphNodes;
myUpEdges = upEdges;
myDownEdges = downEdges;
}
@NotNull
@Override
public GraphNode.Type getNodeType(int nodeIndex) {
return myGraphNodes.get(nodeIndex).getType();
}
@NotNull
@Override
public GraphEdge.Type getEdgeType(int upNodeIndex, int downNodeIndex) {
for (GraphEdge downEdge : myDownEdges.get(upNodeIndex)) {
if (downEdge.getDownNodeIndex() == downNodeIndex)
return downEdge.getType();
}
throw new IllegalStateException("Not found edge: " + upNodeIndex + ", " + downNodeIndex);
}
@Override
public int nodesCount() {
return myGraphNodes.size();
}
@NotNull
@Override
public List<Integer> getUpNodes(int nodeIndex) {
List<Integer> result = new ArrayList<Integer>();
for (GraphEdge upEdge : myUpEdges.get(nodeIndex)) {
result.add(upEdge.getUpNodeIndex());
}
return result;
}
@NotNull
@Override
public List<Integer> getDownNodes(int nodeIndex) {
List<Integer> result = new ArrayList<Integer>();
for (GraphEdge downEdge : myDownEdges.get(nodeIndex)) {
result.add(downEdge.getDownNodeIndex());
}
return result;
}
}
}