/******************************************************************************* * Copyright (c) 2007 Cambridge Semantics Incorporated. * 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: * Cambridge Semantics Incorporated - initial API and implementation *******************************************************************************/ package org.openanzo.glitter.query; import java.util.ArrayList; import java.util.Collections; import org.openanzo.exceptions.AnzoException; import org.openanzo.exceptions.AnzoRuntimeException; import org.openanzo.exceptions.ExceptionConstants; import org.openanzo.glitter.expression.builtin.Bound; import org.openanzo.glitter.expression.builtin.IsLiteral; import org.openanzo.glitter.expression.builtin.Lang; import org.openanzo.glitter.expression.builtin.LangMatches; import org.openanzo.glitter.expression.builtin.LogicalOr; import org.openanzo.glitter.expression.builtin.Not; import org.openanzo.glitter.expression.builtin.PolymorphicEq; import org.openanzo.glitter.syntax.abstrakt.BGP; import org.openanzo.glitter.syntax.abstrakt.Expression; import org.openanzo.glitter.syntax.abstrakt.FunctionCall; import org.openanzo.glitter.syntax.abstrakt.Group; import org.openanzo.glitter.syntax.abstrakt.SimpleExpression; import org.openanzo.glitter.syntax.abstrakt.TreeNode; import org.openanzo.glitter.syntax.abstrakt.TriplePatternNode; import org.openanzo.glitter.syntax.concrete.ParseException; import org.openanzo.rdf.MemPlainLiteral; import org.openanzo.rdf.TriplePatternComponent; import org.openanzo.rdf.Variable; /** * Filters out all plain literals containing a language tag that does not match the provided RFC 3066 language tag. * * The filter is of the form: * * !bound(?var) || !isLiteral(?var) || lang(?var) == '' || langMatches(lang(?var), '<lang>') * * @author Joe Betz <jpbetz@cambridgesemantics.com> * */ public class LangFilteringRewriter implements TreeRewriter { private final String lang; /** * Rewriter that uses the lang tags of literals * * @param lang */ public LangFilteringRewriter(String lang) { this.lang = lang; } public TreeNode rewriteTreeNode(TreeNode node) { try { if (node instanceof BGP) { BGP bgp = (BGP) node; BGP newBgp = bgp.clone(); TreeNode parent = newBgp.getParent(); boolean returnParent = false; Group parentGroup = null; if (parent instanceof Group) { parentGroup = (Group) parent; } else { parentGroup = new Group(); parentGroup.addChild(bgp); returnParent = true; } for (TriplePatternNode tp : bgp.getTriplePatterns()) { TriplePatternComponent obj = tp.getTriplePattern().getObject(); if (obj instanceof Variable) { Variable var = (Variable) obj; ArrayList<Expression> langMatchParams = new ArrayList<Expression>(); langMatchParams.add(new FunctionCall(new Lang(), Collections.<Expression> singletonList(new SimpleExpression(var)))); langMatchParams.add(new SimpleExpression(MemPlainLiteral.create(lang))); FunctionCall langMatches = new FunctionCall(new LangMatches(), langMatchParams); FunctionCall isLiteral = new FunctionCall(new Not(), Collections.<Expression> singletonList(new FunctionCall(new IsLiteral(), Collections.<Expression> singletonList(new SimpleExpression(var))))); ArrayList<Expression> equalsParams = new ArrayList<Expression>(); equalsParams.add(new FunctionCall(new Lang(), Collections.<Expression> singletonList(new SimpleExpression(var)))); equalsParams.add(new SimpleExpression(MemPlainLiteral.create(""))); FunctionCall langEquals = new FunctionCall(new PolymorphicEq(), equalsParams); FunctionCall bound = new FunctionCall(new Not(), Collections.<Expression> singletonList(new FunctionCall(new Bound(), Collections.<Expression> singletonList(new SimpleExpression(var))))); ArrayList<Expression> orParams = new ArrayList<Expression>(); ArrayList<Expression> or2Params = new ArrayList<Expression>(); ArrayList<Expression> or3Params = new ArrayList<Expression>(); or3Params.add(langEquals); or3Params.add(langMatches); FunctionCall or3 = new FunctionCall(new LogicalOr(), or3Params); or2Params.add(isLiteral); or2Params.add(or3); FunctionCall or2 = new FunctionCall(new LogicalOr(), or2Params); orParams.add(bound); orParams.add(or2); FunctionCall or = new FunctionCall(new LogicalOr(), orParams); parentGroup.addFilter(or); } if (returnParent) { return parentGroup; } else { return newBgp; } } } return node; } catch (ParseException e) { throw new AnzoRuntimeException(new AnzoException(ExceptionConstants.GLITTER.REWRITE_EXCEPTION, e, node.toString())); } } }