/*
* 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() ; }
}