1 /* Copyright 2004 The Apache Software Foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package org.apache.xmlbeans; 17 18 import java.util.Iterator; 19 import java.util.Collection; 20 import java.util.List; 21 import java.util.ListIterator; 22 23 /** 24 * The immutable {@link List} returned for XML simple list values. 25 * 26 * XmlSimpleList implements an equals() and hashCode() that compare list 27 * contents, so two XmlSimpleLists are the same if they have the same 28 * values in the same order. 29 */ 30 public class XmlSimpleList implements List, java.io.Serializable 31 { 32 private static final long serialVersionUID = 1L; 33 34 private List underlying; 35 36 /** 37 * Constructs an immutable XmlSimpleList that wraps (does not copy) 38 * the given {@link List}. All non-mutating methods delegate to 39 * the underlying List instance. 40 */ 41 public XmlSimpleList(List list) { this.underlying = list; } 42 43 /** Returns the number of elements in this list. */ 44 public int size() { return underlying.size(); } 45 /** True if the list is empty. */ 46 public boolean isEmpty() { return underlying.isEmpty(); } 47 /** True if the list is contains an object equal to o. */ 48 public boolean contains(Object o) { return underlying.contains(o); } 49 /** True if the list is contains all the objects in the given collection. */ 50 public boolean containsAll(Collection coll) { return underlying.containsAll(coll); } 51 /** Copies the collection to an array. */ 52 public Object[] toArray() { return underlying.toArray(); } 53 /** Copies the collection to an array of a specified type. */ 54 public Object[] toArray(Object[] a) { return underlying.toArray(a); } 55 56 /** Unsupported because this list is immutable. */ 57 public boolean add(Object o) { throw new UnsupportedOperationException(); } 58 /** Unsupported because this list is immutable. */ 59 public boolean addAll(Collection coll) { throw new UnsupportedOperationException(); } 60 /** Unsupported because this list is immutable. */ 61 public boolean remove(Object o) { throw new UnsupportedOperationException(); } 62 /** Unsupported because this list is immutable. */ 63 public boolean removeAll(Collection coll) { throw new UnsupportedOperationException(); } 64 /** Unsupported because this list is immutable. */ 65 public boolean retainAll(Collection coll) { throw new UnsupportedOperationException(); } 66 /** Unsupported because this list is immutable. */ 67 public void clear() { throw new UnsupportedOperationException(); } 68 69 /** Returns the object at the specified position in this list. */ 70 public Object get(int index) { return underlying.get(index); } 71 /** Unsupported because this list is immutable. */ 72 public Object set(int index, Object element) { throw new UnsupportedOperationException(); } 73 /** Unsupported because this list is immutable. */ 74 public void add(int index, Object element) { throw new UnsupportedOperationException(); } 75 /** Unsupported because this list is immutable. */ 76 public Object remove(int index) { throw new UnsupportedOperationException(); } 77 /** Returns index of the first occurance of an object equal to o. */ 78 public int indexOf(Object o) { return underlying.indexOf(o); } 79 /** Returns index of the last occurance of an object equal to o. */ 80 public int lastIndexOf(Object o) { return underlying.lastIndexOf(o); } 81 /** Unsupported because this list is immutable. */ 82 public boolean addAll(int index, Collection c) { throw new UnsupportedOperationException(); } 83 /** Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. */ 84 public List subList(int from, int to) { return new XmlSimpleList(underlying.subList(from, to)); } 85 86 /** Returns an iterator over the elements in this list in proper sequence. */ 87 public Iterator iterator() 88 { 89 return new Iterator() 90 { 91 Iterator i = underlying.iterator(); 92 public boolean hasNext() { return i.hasNext(); } 93 public Object next() { return i.next(); } 94 public void remove() { throw new UnsupportedOperationException(); } 95 }; 96 } 97 98 /** Returns a list iterator of the elements in this list in proper sequence. */ 99 public ListIterator listIterator() { return listIterator(0); } 100 /** Returns a list iterator of the elements in this list in proper sequence, starting at the specified position in this list. */ 101 public ListIterator listIterator(final int index) 102 { 103 return new ListIterator() 104 { 105 ListIterator i = underlying.listIterator(index); 106 107 public boolean hasNext() { return i.hasNext(); } 108 public Object next() { return i.next(); } 109 public boolean hasPrevious(){ return i.hasPrevious(); } 110 public Object previous() { return i.previous(); } 111 public int nextIndex() { return i.nextIndex(); } 112 public int previousIndex() { return i.previousIndex(); } 113 114 public void remove() { throw new UnsupportedOperationException(); } 115 public void set(Object o) { throw new UnsupportedOperationException(); } 116 public void add(Object o) { throw new UnsupportedOperationException(); } 117 }; 118 } 119 120 private String stringValue(Object o) 121 { 122 if (o instanceof SimpleValue) 123 return ((SimpleValue)o).stringValue(); 124 return o.toString(); 125 } 126 127 /** 128 * Returns a space-separated list of the string representations of all 129 * the items in the list. For most lists, this is a valid xml lexical 130 * value for the list. (The notable exception is a list of QNames.) 131 */ 132 public String toString() 133 { 134 int size = underlying.size(); 135 if (size == 0) 136 return ""; 137 String first = stringValue(underlying.get(0)); 138 if (size == 1) 139 return first; 140 StringBuffer result = new StringBuffer(first); 141 for (int i = 1; i < size; i++) 142 { 143 result.append(' '); 144 result.append(stringValue(underlying.get(i))); 145 } 146 return result.toString(); 147 } 148 149 /** 150 * Two XmlSimpleLists are equal if all their items are equal. 151 * (They must have the same number of items, and the items must be in 152 * the same order.) 153 */ 154 public boolean equals(Object o) 155 { 156 if (this == o) return true; 157 if (!(o instanceof XmlSimpleList)) return false; 158 final XmlSimpleList xmlSimpleList = (XmlSimpleList)o; 159 List underlying2 = xmlSimpleList.underlying; 160 int size = underlying.size(); 161 if (size != underlying2.size()) 162 return false; 163 for (int i = 0; i < size; i++) 164 { 165 Object item = underlying.get(i); 166 Object item2 = underlying2.get(i); 167 if (item == null ? item2 != null : !item.equals(item2)) 168 return false; 169 } 170 return true; 171 } 172 173 /** 174 * Combines the hash codes of all the list items. 175 */ 176 public int hashCode() 177 { 178 int size = underlying.size(); 179 int hash = 0; 180 for (int i = 0; i < size; i++) 181 { 182 Object item = underlying.get(i); 183 hash *= 19; 184 hash += item.hashCode(); 185 } 186 return hash; 187 } 188 }