/* * 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; import java.util.ArrayList ; import java.util.Iterator ; import java.util.List ; import org.apache.jena.graph.Node ; public class ItemList extends ItemLocation implements Iterable<Item> { private final List<Item> elements ; // Pointer to the start of the list // Because of repeated cdr's, we can not use a .subList (leads to a whole // chain subLists, one per call). private final int offset ; private int index(int i) { return offset+i ; } private int _size() { return elements.size()-offset; } private List<Item> slice() { return elements.subList(offset, elements.size()) ; } public ItemList(int line, int column) { this(line, column, 0, new ArrayList<Item>()) ; } public ItemList() { this(noLine, noColumn) ; } public ItemList(int line, int column, int offset, List<Item> elts) { super(line, column) ; this.elements = elts ; this.offset = offset ; } public int size() { return _size() ; } public boolean isEmpty() { return _size()==0 ; } @Override public int hashCode() { return elements.hashCode() ^ offset ; } @Override public boolean equals(Object other) { if ( this == other ) return true ; if ( ! ( other instanceof ItemList) ) return false ; ItemList list = (ItemList)other ; if ( list.size() != size() ) return false ; return slice().equals(list.slice()) ; } public void addAll(ItemList itemList) { elements.addAll(itemList.elements) ; } public void add(Item item){ elements.add(item) ; } public void add(Node node){ elements.add(Item.createNode(node)) ; } public void add(String symbol){ elements.add(Item.createSymbol(symbol)) ; } public Item get(int idx) { return elements.get(index(idx)) ; } public Item getFirst() { return get(0) ; } public Item getLast() { return get(_size()-1) ; } @Override public Iterator<Item> iterator() { return elements.listIterator(offset) ; } public Item car() { if ( _size() == 0 ) throw new ItemException("ItemList.car: list is zero length") ; return get(0) ; } public ItemList cdr() { if ( _size() == 0 ) throw new ItemException("ItemList.cdr: list is zero length") ; ItemList x = new ItemList(super.getLine(), super.getColumn(), offset+1, elements) ; return x ; } public ItemList cdrOrNull() { if ( _size() == 0 ) return null ; ItemList x = new ItemList(super.getLine(), super.getColumn(), offset+1, elements) ; return x ; } public ItemList sublist(int start) { if ( _size() < start+offset ) return null ; ItemList x = new ItemList(noLine, noColumn, offset+start, elements) ; return x ; } /** Slice of the list from start (inclusive) to finish (exclusive) */ public ItemList sublist(int start, int finish) { if ( start < 0 || finish < 0 || finish < start ) return null ; if ( _size() < start ) return null ; if ( finish > _size() ) return null ; ItemList x = new ItemList() ; // Take a slice. // Note : this is a copy. // Note: List.subList just puts a wrapper around the overlying list // but don't do this a lot because ArrayList.get recurses to the core list (may run out of stack). // Better would an adjusting slice over base array but it's quite tricky to do the calculations correctly. // This way is mnore likely to be correct. x.elements.addAll(elements.subList(start+offset, finish+offset)) ; return x ; } public String shortString() { if ( _size() == 0 ) return "()" ; if ( get(0).isSymbol() ) { if ( _size() == 1 ) return "("+get(0).getSymbol()+")"; else return "("+get(0).getSymbol()+" ...)"; } return "(...)" ; } @Override public String toString() { String str = "" ; if ( hasLocation() ) str = str.concat(location()) ; return str+slice().toString() ; } }