/* * 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.syntax; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.jena.graph.Node; import org.apache.jena.graph.Triple; import org.apache.jena.sparql.core.BasicPattern; import org.apache.jena.sparql.core.Quad; import org.apache.jena.sparql.engine.binding.Binding; import org.apache.jena.sparql.modify.TemplateLib; import org.apache.jena.sparql.modify.request.QuadAcc; import org.apache.jena.sparql.serializer.FormatterTemplate; import org.apache.jena.sparql.util.Iso; import org.apache.jena.sparql.util.NodeIsomorphismMap; /** Quads/Triples template. */ public class Template { static final int HashTemplateGroup = 0xB1 ; private final QuadAcc qp ; private final BasicPattern bgp; public Template(QuadAcc qp) { this.qp = qp ; this.bgp = null; } public Template(BasicPattern bgp) { this.bgp = bgp; this.qp = null; } // public void addTriple(Triple t) { quads.addTriple(t) ; } // public int mark() { return quads.mark() ; } // public void addTriple(int index, Triple t) { quads.addTriple(index, t) ; } // public void addTriplePath(TriplePath path) // { throw new ARQException("Triples-only collector") ; } // // public void addTriplePath(int index, TriplePath path) // { throw new ARQException("Triples-only collector") ; } public boolean containsRealQuad(){ for(Quad quad : this.getQuads()){ if ( ! Quad.defaultGraphNodeGenerated.equals( quad.getGraph())){ return true; } } return false; } public BasicPattern getBGP() { if (this.bgp != null){ return this.bgp; } BasicPattern bgp = new BasicPattern(); for(Quad q: qp.getQuads()){ if (Quad.defaultGraphNodeGenerated.equals(q.getGraph())) bgp.add(q.asTriple()); } return bgp; } public List<Triple> getTriples() { if(this.bgp != null){ return this.bgp.getList(); } List<Triple> triples = new ArrayList<Triple>(); for(Quad q: qp.getQuads()){ if (Quad.defaultGraphNodeGenerated.equals(q.getGraph())) triples.add(q.asTriple()); } return triples; } public List<Quad> getQuads() { if( this.bgp != null){ List<Quad> quads = new ArrayList<Quad>(); for(Triple triple: this.bgp.getList()){ quads.add( new Quad( Quad.defaultGraphNodeGenerated, triple ) ); } return quads; } return qp.getQuads() ; } public Map<Node, BasicPattern> getGraphPattern(){ List<Quad> quads = getQuads(); HashMap<Node, BasicPattern> graphs = new HashMap<>(); for (Quad q: quads){ BasicPattern bgp = graphs.get(q.getGraph()); if (bgp == null){ bgp = new BasicPattern(); graphs.put(q.getGraph(), bgp); } bgp.add( q.asTriple() ); } return graphs; } // ------------------------- public void subst(Collection<Triple> acc, Map<Node, Node> bNodeMap, Binding b) { for ( Triple t : getTriples() ) { t = TemplateLib.subst(t, b, bNodeMap) ; acc.add(t) ; } } private int calcHashCode = -1 ; @Override public int hashCode() { // BNode invariant hashCode. int calcHashCode = Template.HashTemplateGroup ; for ( Quad q : getQuads() ) calcHashCode ^= hash(q) ^ calcHashCode<<1 ; return calcHashCode ; } private static int hash(Quad quad) { int hash = 0 ; hash = hashNode(quad.getSubject()) ^ hash<<1 ; hash = hashNode(quad.getPredicate()) ^ hash<<1 ; hash = hashNode(quad.getObject()) ^ hash<<1 ; hash = hashGraph(quad.getGraph()) ^ hash<<1 ; return hash ; } private static int hashGraph(Node node){ if ( node == null ) return Quad.defaultGraphNodeGenerated.hashCode() ; if ( node.isBlank() ) return 59 ; return node.hashCode() ; } private static int hashNode(Node node) { if ( node == null ) return 37 ; if ( node.isBlank() ) return 59 ; return node.hashCode() ; } public boolean equalIso(Object temp2, NodeIsomorphismMap labelMap) { if ( ! ( temp2 instanceof Template) ) return false ; Template tg2 = (Template)temp2 ; List<Quad> list1 = this.getQuads() ; List<Quad> list2 = tg2.getQuads() ; if ( list1.size() != list2.size() ) return false ; for ( int i = 0 ; i < list1.size() ; i++ ) { Quad q1 = list1.get(i) ; Quad q2 = list2.get(i) ; boolean iso = Iso.quadIso(q1, q2, labelMap) ; if(!iso){ return false; } } return true ; } public void format(FormatterTemplate fmtTemplate) { fmtTemplate.format(this) ; } }