/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.jena.sparql.sse.writers;
import org.apache.jena.atlas.io.IndentedLineBuffer ;
import org.apache.jena.atlas.io.IndentedWriter ;
import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.core.Prologue ;
import org.apache.jena.sparql.core.TriplePath ;
import org.apache.jena.sparql.path.* ;
import org.apache.jena.sparql.serializer.SerializationContext ;
import org.apache.jena.sparql.sse.Tags ;
import org.apache.jena.sparql.util.FmtUtils ;
/** SSE Writer */
public class WriterPath
{
private static final int NL = WriterLib.NL ;
private static final int NoNL = WriterLib.NoNL ;
private static final int NoSP = WriterLib.NoSP ;
public static void write(Path path, Prologue prologue)
{
output(IndentedWriter.stdout, path, new SerializationContext(prologue)) ;
}
public static void output(IndentedWriter out, Path path, SerializationContext naming)
{
WriterPathVisitor w = new WriterPathVisitor(out, naming.getPrologue()) ;
w.output(path) ;
w.out.flush();
}
public static void output(IndentedWriter out, TriplePath tp, SerializationContext naming)
{
WriterLib.start(out, Tags.tagTriplePath, NoNL) ;
outputPlain(out, tp, naming) ;
WriterLib.finish(out, Tags.tagTriplePath) ;
}
public static void outputPlain(IndentedWriter out, TriplePath tp, SerializationContext naming)
{
boolean oneLiner = oneLiner(tp.getPath()) ;
if ( oneLiner )
{
WriterNode.output(out, tp.getSubject(), naming) ;
out.print(" ") ;
WriterPath.output(out, tp.getPath(), naming) ;
out.print(" ") ;
WriterNode.output(out, tp.getObject(), naming) ;
}
else
{
nl(out, false);
WriterNode.output(out, tp.getSubject(), naming) ;
nl(out);
WriterPath.output(out, tp.getPath(), naming) ;
nl(out);
WriterNode.output(out, tp.getObject(), naming) ;
}
}
private static boolean oneLiner(Path path)
{
return (path instanceof P_Link) ;
}
private static final boolean multiline = false ;
private static final boolean maxBracket = false ;
private static void nl(IndentedWriter out)
{
nl(out, true) ;
}
private static void nl(IndentedWriter out, boolean spaceForNL)
{
if ( multiline )
out.println();
else
if ( spaceForNL ) out.print(" ") ;
}
public static String asString(Path path) { return asString(path, null) ; }
public static String asString(Path path, Prologue prologue)
{
IndentedLineBuffer buff = new IndentedLineBuffer() ;
WriterPathVisitor w = new WriterPathVisitor(buff, prologue) ;
path.visit(w) ;
w.out.flush();
return buff.asString() ;
}
private static class WriterPathVisitor implements PathVisitor
{
private IndentedWriter out ;
private Prologue prologue ;
WriterPathVisitor(IndentedWriter indentedWriter, Prologue prologue)
{
this.out = indentedWriter ;
this.prologue = prologue ;
}
private void output(Path path)
{
path.visit(this) ;
}
private void output(Node node)
{
out.print(FmtUtils.stringForNode(node, prologue)) ;
}
@Override
public void visit(P_Link pathNode)
{
output(pathNode.getNode()) ;
}
@Override
public void visit(P_ReverseLink pathNode)
{
out.print("(") ;
out.print(Tags.tagPathRev) ;
out.print(" ") ;
output(pathNode.getNode()) ;
out.print(")") ;
}
@Override
public void visit(P_NegPropSet pathNotOneOf)
{
out.print("(") ;
out.print(Tags.tagPathNotOneOf) ;
for ( P_Path0 p : pathNotOneOf.getNodes() )
{
out.print(" ") ;
output(p) ;
}
out.print(")") ;
}
@Override
public void visit(P_Alt pathAlt)
{
visit2(pathAlt, Tags.tagPathAlt) ;
}
@Override
public void visit(P_Seq pathSeq)
{
visit2(pathSeq, Tags.tagPathSeq) ;
}
private void visit2(P_Path2 path2, String nodeName)
{
out.print("(") ;
out.print(nodeName) ;
nl(out) ;
out.incIndent() ;
output(path2.getLeft()) ;
nl(out) ;
output(path2.getRight()) ;
out.decIndent() ;
out.print(")") ;
}
@Override
public void visit(P_Mod pathMod)
{
out.print("(") ;
out.print(Tags.tagPathMod) ;
out.print(" ") ;
out.print(modInt(pathMod.getMin())) ;
out.print(" ") ;
out.print(modInt(pathMod.getMax())) ;
writeOneLiner(pathMod.getSubPath()) ;
out.print(")") ;
}
private static String modInt(long value)
{
if ( value == P_Mod.INF ) return "*" ;
if ( value == P_Mod.UNSET ) return "_" ;
return Long.toString(value) ;
}
@Override
public void visit(P_FixedLength path)
{
out.print("(") ;
out.print(Tags.tagPathFixedLength) ;
out.print(" ") ;
out.print(modInt(path.getCount())) ;
writeOneLiner(path.getSubPath()) ;
out.print(")") ;
}
@Override
public void visit(P_Distinct pathDistinct)
{
writePath(Tags.tagPathDistinct, pathDistinct.getSubPath()) ;
}
@Override
public void visit(P_Multi pathMulti)
{
writePath(Tags.tagPathMulti, pathMulti.getSubPath()) ;
}
@Override
public void visit(P_Shortest path)
{
writePath(Tags.tagPathShortest, path.getSubPath()) ;
}
@Override
public void visit(P_ZeroOrOne path)
{
writePath(Tags.tagPathZeroOrOne, path.getSubPath()) ;
}
@Override
public void visit(P_ZeroOrMore1 path)
{
writePath(Tags.tagPathZeroOrMore1, path.getSubPath()) ;
}
@Override
public void visit(P_ZeroOrMoreN path)
{
writePath(Tags.tagPathZeroOrMoreN, path.getSubPath()) ;
}
@Override
public void visit(P_OneOrMore1 path)
{
writePath(Tags.tagPathOneOrMore1, path.getSubPath()) ;
}
@Override
public void visit(P_OneOrMoreN path)
{
writePath(Tags.tagPathOneOrMoreN, path.getSubPath()) ;
}
private void writeOneLiner(Path path)
{
if ( oneLiner(path) )
out.print(" ") ;
else
nl(out) ;
out.incIndent() ;
output(path) ;
out.decIndent() ;
}
private void writePath(String tag, Path subPath)
{
out.print("(") ;
out.print(tag) ;
writeOneLiner(subPath) ;
out.print(")") ;
}
@Override
public void visit(P_Inverse reversePath)
{
out.print("(") ;
out.print(Tags.tagPathReverse) ;
nl(out) ;
out.incIndent() ;
Path p = reversePath.getSubPath() ;
output(p) ;
out.decIndent() ;
nl(out, false) ;
out.print(")") ;
}
}
}