1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.impl.xs.util; 22 23 import com.sun.org.apache.xerces.internal.xs.XSObject; 24 import com.sun.org.apache.xerces.internal.xs.XSObjectList; 25 import java.lang.reflect.Array; 26 import java.util.AbstractList; 27 import java.util.Iterator; 28 import java.util.ListIterator; 29 import java.util.NoSuchElementException; 30 31 /** 32 * Containts a list of XSObject's. 33 * 34 * @xerces.internal 35 * 36 * @author Sandy Gao, IBM 37 * 38 * @LastModified: Oct 2017 39 */ 40 @SuppressWarnings("unchecked") // method <T>toArray(T[]) 41 public class XSObjectListImpl extends AbstractList<XSObject> implements XSObjectList { 42 43 /** 44 * An immutable empty list. 45 */ 46 public static final XSObjectListImpl EMPTY_LIST = new XSObjectListImpl(new XSObject[0], 0); 47 private static final ListIterator<XSObject> EMPTY_ITERATOR = new EmptyIterator(); 48 static class EmptyIterator implements ListIterator<XSObject> { 49 public boolean hasNext() { 50 return false; 51 } 52 public XSObject next() { 53 throw new NoSuchElementException(); 54 } 55 public boolean hasPrevious() { 56 return false; 57 } 58 public XSObject previous() { 59 throw new NoSuchElementException(); 60 } 61 public int nextIndex() { 62 return 0; 63 } 64 public int previousIndex() { 65 return -1; 66 } 67 public void remove() { 68 throw new UnsupportedOperationException(); 69 } 70 public void set(XSObject object) { 71 throw new UnsupportedOperationException(); 72 } 73 public void add(XSObject object) { 74 throw new UnsupportedOperationException(); 75 } 76 } 77 private static final int DEFAULT_SIZE = 4; 78 79 // The array to hold all data 80 private XSObject[] fArray = null; 81 // Number of elements in this list 82 private int fLength = 0; 83 84 public XSObjectListImpl() { 85 fArray = new XSObject[DEFAULT_SIZE]; 86 fLength = 0; 87 } 88 89 /** 90 * Construct an XSObjectList implementation 91 * 92 * @param array the data array 93 * @param length the number of elements 94 */ 95 public XSObjectListImpl(XSObject[] array, int length) { 96 fArray = array; 97 fLength = length; 98 } 99 100 /** 101 * The number of <code>XSObjects</code> in the list. The range of valid 102 * child node indices is 0 to <code>length-1</code> inclusive. 103 */ 104 public int getLength() { 105 return fLength; 106 } 107 108 /** 109 * Returns the <code>index</code>th item in the collection. The index 110 * starts at 0. If <code>index</code> is greater than or equal to the 111 * number of nodes in the list, this returns <code>null</code>. 112 * @param index index into the collection. 113 * @return The XSObject at the <code>index</code>th position in the 114 * <code>XSObjectList</code>, or <code>null</code> if that is not a 115 * valid index. 116 */ 117 public XSObject item(int index) { 118 if (index < 0 || index >= fLength) { 119 return null; 120 } 121 return fArray[index]; 122 } 123 124 // clear this object 125 public void clearXSObjectList() { 126 for (int i=0; i<fLength; i++) { 127 fArray[i] = null; 128 } 129 fArray = null; 130 fLength = 0; 131 } 132 133 public void addXSObject(XSObject object) { 134 if (fLength == fArray.length) { 135 XSObject[] temp = new XSObject[fLength + 4]; 136 System.arraycopy(fArray, 0, temp, 0, fLength); 137 fArray = temp; 138 } 139 fArray[fLength++] = object; 140 } 141 142 public void addXSObject(int index, XSObject object) { 143 fArray[index] = object; 144 } 145 146 /* 147 * List methods 148 */ 149 150 public boolean contains(Object value) { 151 return (value == null) ? containsNull() : containsObject(value); 152 } 153 154 public XSObject get(int index) { 155 if (index >= 0 && index < fLength) { 156 return fArray[index]; 157 } 158 throw new IndexOutOfBoundsException("Index: " + index); 159 } 160 161 public int size() { 162 return getLength(); 163 } 164 165 public Iterator<XSObject> iterator() { 166 return listIterator0(0); 167 } 168 169 public ListIterator<XSObject> listIterator() { 170 return listIterator0(0); 171 } 172 173 public ListIterator<XSObject> listIterator(int index) { 174 if (index >= 0 && index < fLength) { 175 return listIterator0(index); 176 } 177 throw new IndexOutOfBoundsException("Index: " + index); 178 } 179 180 private ListIterator<XSObject> listIterator0(int index) { 181 return fLength == 0 ? EMPTY_ITERATOR : new XSObjectListIterator(index); 182 } 183 184 private boolean containsObject(Object value) { 185 for (int i = fLength - 1; i >= 0; --i) { 186 if (value.equals(fArray[i])) { 187 return true; 188 } 189 } 190 return false; 191 } 192 193 private boolean containsNull() { 194 for (int i = fLength - 1; i >= 0; --i) { 195 if (fArray[i] == null) { 196 return true; 197 } 198 } 199 return false; 200 } 201 202 public Object[] toArray() { 203 Object[] a = new Object[fLength]; 204 toArray0(a); 205 return a; 206 } 207 208 public Object[] toArray(Object[] a) { 209 if (a.length < fLength) { 210 Class<?> arrayClass = a.getClass(); 211 Class<?> componentType = arrayClass.getComponentType(); 212 a = (Object[]) Array.newInstance(componentType, fLength); 213 } 214 toArray0(a); 215 if (a.length > fLength) { 216 a[fLength] = null; 217 } 218 return a; 219 } 220 221 private void toArray0(Object[] a) { 222 if (fLength > 0) { 223 System.arraycopy(fArray, 0, a, 0, fLength); 224 } 225 } 226 227 private final class XSObjectListIterator implements ListIterator<XSObject> { 228 private int index; 229 public XSObjectListIterator(int index) { 230 this.index = index; 231 } 232 public boolean hasNext() { 233 return (index < fLength); 234 } 235 public XSObject next() { 236 if (index < fLength) { 237 return fArray[index++]; 238 } 239 throw new NoSuchElementException(); 240 } 241 public boolean hasPrevious() { 242 return (index > 0); 243 } 244 public XSObject previous() { 245 if (index > 0) { 246 return fArray[--index]; 247 } 248 throw new NoSuchElementException(); 249 } 250 public int nextIndex() { 251 return index; 252 } 253 public int previousIndex() { 254 return index - 1; 255 } 256 public void remove() { 257 throw new UnsupportedOperationException(); 258 } 259 public void set(XSObject o) { 260 throw new UnsupportedOperationException(); 261 } 262 public void add(XSObject o) { 263 throw new UnsupportedOperationException(); 264 } 265 } 266 267 } // class XSObjectListImpl