001 /* 002 * www.ti.bfh.ch 003 * 004 * Copyright 2007, Berne University of Applied Sciences, 005 * School of Engineering and Information Technology 006 * and individual contributors as indicated by the @authors tag. 007 * 008 * This is free software; you can redistribute it and/or modify it under the terms of the 009 * GNU Lesser General Public License as published by the Free Software Foundation; 010 * either version 3 of the License, or (at your option) any later version. 011 * 012 * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 013 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 014 * See the GNU Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License along with this software; 017 * if not, see <http://www.gnu.org/licenses/>. 018 * 019 */ 020 package ch.bfh.algo.core.sequence; 021 022 023 import java.util.AbstractList; 024 025 import ch.bfh.algo.BoundaryViolationException; 026 import ch.bfh.algo.EmptySequenceException; 027 import ch.bfh.algo.InvalidAccessorException; 028 import ch.bfh.algo.Position; 029 import ch.bfh.algo.core.GenericSequence; 030 import ch.bfh.algo.core.position.PositionIterator; 031 import ch.bfh.algo.core.position.PositionListIterator; 032 import ch.bfh.algo.core.position.PositionListIteratorAdapter; 033 import ch.bfh.algo.sequence.SequenceFactory; 034 035 036 public class GenericArraySequence<E,P extends GenericArrayPosition<E,P>> extends AbstractList<E> implements GenericSequence<E,P>{ 037 038 private PositionArray<E,P> array; 039 private SequenceFactory<P> factory; 040 041 public GenericArraySequence(int size, SequenceFactory<P> factory, ArrayStrategy<P> strategy){ 042 this.factory=factory; 043 this.array=new PositionArray<E,P>(size,strategy); 044 } 045 046 private void validate(P position) throws InvalidAccessorException{ 047 if(position==null || this!=position.container()) throw new InvalidAccessorException(); 048 } 049 050 public boolean encloses(Position<?> position) { 051 try{return this.encloses(this.factory.cast(position));} 052 catch(ClassCastException e){return false;} 053 } 054 055 public boolean encloses(P position){ 056 try{this.validate(position); return true;} 057 catch(InvalidAccessorException e){return false;} 058 } 059 060 public E get(int index) throws IndexOutOfBoundsException{ 061 return this.array.get(index).element(); 062 } 063 064 public int size(){ 065 return this.array.size(); 066 } 067 068 public P first() throws EmptySequenceException{ 069 if(!this.isEmpty())return this.array.get(0); 070 else throw new EmptySequenceException(); 071 } 072 073 public P last() throws EmptySequenceException{ 074 if(!this.isEmpty())return this.array.get(this.size()-1); 075 else throw new EmptySequenceException(); 076 } 077 078 public P before(Position<?> position) throws InvalidAccessorException, BoundaryViolationException { 079 try{return this.before(this.factory.cast(position));} 080 catch(ClassCastException e){throw new InvalidAccessorException();} 081 } 082 083 public P before(P position) throws InvalidAccessorException, BoundaryViolationException{ 084 this.validate(position); 085 int index=position.getRank()-1; 086 if(index>=0) return this.array.get(index); 087 else throw new BoundaryViolationException(); 088 } 089 090 public P after(Position<?> position) throws InvalidAccessorException, BoundaryViolationException { 091 try{return this.after(this.factory.cast(position));} 092 catch(ClassCastException e){throw new InvalidAccessorException();} 093 } 094 095 public P after(P position) throws InvalidAccessorException, BoundaryViolationException{ 096 this.validate(position); 097 int index=position.getRank()+1; 098 if(index<this.size()) return this.array.get(index); 099 else throw new BoundaryViolationException(); 100 } 101 102 public P insertBefore(Position<?> position, E element) throws InvalidAccessorException { 103 try{return this.insertBefore(this.factory.cast(position),element);} 104 catch(ClassCastException e){throw new InvalidAccessorException();} 105 } 106 107 public P insertBefore(P position, E element) throws InvalidAccessorException{ 108 this.validate(position); 109 return this.insertBefore(this.rank(position),element); 110 } 111 112 private P insertBefore(int index, E element){ 113 P position=this.factory.createPosition(); 114 ConcreteLocator<E,P> locator=new ConcreteLocator<E,P>(); 115 locator.setElement(element); 116 locator.setPosition(position); 117 position.setLocator(locator); 118 position.setContainer(this); 119 this.array.insert(index,position); 120 return position; 121 } 122 123 public void add(int index, E element) throws IndexOutOfBoundsException{ 124 this.insertBefore(index,element); 125 } 126 127 public P insertAfter(Position<?> position, E element) throws InvalidAccessorException { 128 try{return this.insertAfter(this.factory.cast(position),element);} 129 catch(ClassCastException e){throw new InvalidAccessorException();} 130 } 131 132 public P insertAfter(P position, E element) throws InvalidAccessorException{ 133 this.validate(position); 134 return this.insertBefore(this.rank(position)+1,element); 135 } 136 137 public P insert(E element){ 138 return this.insertBefore(this.size(),element); 139 } 140 141 public P position(int rank) throws IndexOutOfBoundsException{ 142 return this.array.get(rank); 143 } 144 145 public int rank(Position<?> position) { 146 try{return this.rank(this.factory.cast(position));} 147 catch(ClassCastException e){return -1;} 148 } 149 150 public int rank(P position){ 151 try{ 152 this.validate(position); 153 return position.getRank(); 154 }catch(InvalidAccessorException e){return -1;} 155 } 156 157 public E replace(Position<?> position, E element) throws InvalidAccessorException { 158 try{return this.replace(this.factory.cast(position),element);} 159 catch(ClassCastException e){throw new InvalidAccessorException();} 160 } 161 162 public E replace(P position, E element) throws InvalidAccessorException{ 163 this.validate(position); 164 return position.replace(position,element); 165 } 166 167 public E element(Position<?> position){ 168 try{return this.element(this.factory.cast(position));} 169 catch(ClassCastException e){throw new InvalidAccessorException();} 170 } 171 172 public E element(P position){ 173 this.validate(position); 174 return position.element(); 175 } 176 177 public E set(int index, E element) throws IndexOutOfBoundsException{ 178 P p=this.array.get(index); 179 return p.replace(p,element); 180 } 181 182 public E delete(Position<?> position) throws InvalidAccessorException { 183 try{return this.delete(this.factory.cast(position));} 184 catch(ClassCastException e){throw new InvalidAccessorException();} 185 } 186 187 public E delete(P position) throws InvalidAccessorException{ 188 this.validate(position); 189 return this.remove(position.getRank()); 190 } 191 192 public E remove(int index) throws IndexOutOfBoundsException{ 193 P position=this.array.delete(index); 194 E element=position.element(); 195 position.locator().setPosition(null); 196 position.setLocator(null); 197 position.setContainer(null); 198 return element; 199 } 200 201 public void swap(Position<?> position0, Position<?> position1) throws InvalidAccessorException { 202 try{this.swap(this.factory.cast(position0),this.factory.cast(position1));} 203 catch(ClassCastException e){throw new InvalidAccessorException();} 204 } 205 206 public void swap(P position0, P position1) throws InvalidAccessorException{ 207 this.validate(position0); 208 this.validate(position1); 209 position0.swap(position0,position1); 210 } 211 212 public PositionIterator<E,P> positionIterator(){ 213 return this.positionListIterator(0); 214 } 215 216 public PositionListIterator<E,P> positionListIterator(final int rank){ 217 return new PositionListIteratorAdapter<E,P>(GenericArraySequence.this.array.listIterator(rank)); 218 } 219 220 public PositionListIterator<E,P> positionListIterator(){ 221 return this.positionListIterator(0); 222 } 223 224 }