/*
* Copyright 2015 by Thomas Lottermann
*
* 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 notaql.engines.csv.path;
import notaql.datamodel.Step;
import notaql.model.EvaluationException;
import notaql.model.path.*;
import notaql.parser.TransformationParser;
import notaql.parser.antlr.*;
import org.antlr.v4.runtime.misc.NotNull;
import java.util.LinkedList;
import java.util.List;
/**
* The visitor that produces inputpaths for the CSV engine
*/
public class CSVInputPathVisitor extends NotaQL2CSVInBaseVisitor<InputPath> {
private final TransformationParser parser;
private boolean relative;
public CSVInputPathVisitor(TransformationParser parser, boolean relative) {
this.parser = parser;
this.relative = relative;
}
/**
* Parses the split() method
*
* @param ctx
* @return
*/
@Override
public InputPath visitSplittedInputPath(@NotNull NotaQL2CSVInParser.SplittedInputPathContext ctx) {
final List<InputPathStep> pathSteps = new LinkedList<>(visit(ctx.firstInputPathStep()).getPathSteps());
if (ctx.atom() != null) {
String string = ctx.atom().getText().replace("\\'", "'");
string = string.substring(1, string.length() - 1);
pathSteps.add(new StringSplitMethodStep(string));
} else {
pathSteps.add(new StringSplitMethodStep());
}
pathSteps.add(new AnyBoundCurrentStep());
return new InputPath(relative, pathSteps);
}
/**
* Parses a cell step.
*
* @param ctx
* @return
*/
@Override
public InputPath visitCellInputPathStep(@NotNull NotaQL2CSVInParser.CellInputPathStepContext ctx) {
List<InputPathStep> pathSteps = new LinkedList<>();
if (ctx.predicate() == null)
pathSteps.add(new AnyBoundCurrentStep());
else
pathSteps.add(new PredicateStep(parser.getPredicateVisitor().evaluate(ctx.predicate().getText())));
if (ctx.source.getType() == NotaQL2CSVInParser.Col)
pathSteps.add(new NamePathMethodStep());
return new InputPath(relative, pathSteps);
}
/**
* Parses a constant column id and produces a matching step (IN.constant)
*
* @param ctx
* @return
*/
@Override
public InputPath visitColIdInputPathStep(@NotNull NotaQL2CSVInParser.ColIdInputPathStepContext ctx) {
return new InputPath(
relative,
new IdStep<>(new Step<>(ctx.colId().colName.getText()))
);
}
/**
* Parses a resolved input path (IN.$(IN.a))
*
* @param ctx
* @return
*/
@Override
public InputPath visitResolvedInputPathStep(@NotNull NotaQL2CSVInParser.ResolvedInputPathStepContext ctx) {
return new InputPath(
relative,
new ResolvedIdStep(parser.getInputPathVisitor().evaluateAbsolute(ctx.absoluteInputPath().path().getText()))
);
}
/**
* In case of a relative path (i.e. @) we simply create a new root of a path.
* In any other case its not permitted.
*
* @param ctx
* @return
*/
@Override
public InputPath visitRelativeCurrentCellPathStep(@NotNull NotaQL2CSVInParser.RelativeCurrentCellPathStepContext ctx) {
if (!relative)
throw new EvaluationException("'IN' is not allowed as input path");
return new InputPath(
true
);
}
}