package com.tesora.dve.sql.expression; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.util.LinkedList; import java.util.List; import com.tesora.dve.sql.SchemaException; import com.tesora.dve.sql.ParserException.Pass; import com.tesora.dve.sql.node.Edge; import com.tesora.dve.sql.node.LanguageNode; import com.tesora.dve.sql.node.test.EdgeTest; import com.tesora.dve.sql.util.Functional; import com.tesora.dve.sql.util.UnaryPredicate; public final class ExpressionPath { private List<Edge<?,?>> steps; private ExpressionPath(List<Edge<?,?>> p) { steps = p; } public LanguageNode apply(LanguageNode in) { LanguageNode p = in; for(Edge<?,?> e : steps) { LanguageNode o = e.apply(p); if (o == null) return null; p = o; } return p; } public int size() { return steps.size(); } @SuppressWarnings("unchecked") public <T extends LanguageNode> void update(LanguageNode in, T repl) { T target = (T) apply(in); Edge<?,T> parentEdge = target.getParentEdge(); parentEdge.set(repl); } public boolean has(UnaryPredicate<Edge<?,?>> predicate) { return Functional.any(steps, predicate); } public boolean has(final EdgeTest et) { return has(new UnaryPredicate<Edge<?,?>>() { @Override public boolean test(Edge<?, ?> object) { return object.getName().baseMatches(et.getName()); } }); } public static ExpressionPath build(LanguageNode from, LanguageNode to) { LinkedList<Edge<?,?>> path = new LinkedList<Edge<?,?>>(); LanguageNode p = from; while (p != to && p != null) { Edge<?,?> parentEdge = p.getParentEdge(); path.add(0, parentEdge); if (parentEdge == null) // went too far return null; p = parentEdge.getParent(); } if (path.isEmpty()) throw new SchemaException(Pass.PLANNER, "Built empty expression path"); return new ExpressionPath(path); } }