Java tutorial
/* * 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.pdfbox.cos; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Objects; import org.apache.pdfbox.pdmodel.common.COSObjectable; /** * An array of PDFBase objects as part of the PDF document. * * @author Ben Litchfield */ public class COSArray extends COSBase implements Iterable<COSBase>, COSUpdateInfo { private final List<COSBase> objects = new ArrayList<>(); private boolean needToBeUpdated; /** * Constructor. */ public COSArray() { //default constructor } /** * This will add an object to the array. * * @param object The object to add to the array. */ public void add(COSBase object) { objects.add(object); } /** * This will add an object to the array. * * @param object The object to add to the array. */ public void add(COSObjectable object) { objects.add(object.getCOSObject()); } /** * Add the specified object at the ith location and push the rest to the * right. * * @param i The index to add at. * @param object The object to add at that index. */ public void add(int i, COSBase object) { objects.add(i, object); } /** * This will remove all of the objects in the collection. */ public void clear() { objects.clear(); } /** * This will remove all of the objects in the collection. * * @param objectsList The list of objects to remove from the collection. */ public void removeAll(Collection<COSBase> objectsList) { objects.removeAll(objectsList); } /** * This will retain all of the objects in the collection. * * @param objectsList The list of objects to retain from the collection. */ public void retainAll(Collection<COSBase> objectsList) { objects.retainAll(objectsList); } /** * This will add an object to the array. * * @param objectsList The object to add to the array. */ public void addAll(Collection<COSBase> objectsList) { objects.addAll(objectsList); } /** * This will add all objects to this array. * * @param objectList The objects to add. */ public void addAll(COSArray objectList) { if (objectList != null) { objects.addAll(objectList.objects); } } /** * Add the specified object at the ith location and push the rest to the * right. * * @param i The index to add at. * @param objectList The object to add at that index. */ public void addAll(int i, Collection<COSBase> objectList) { objects.addAll(i, objectList); } /** * This will set an object at a specific index. * * @param index zero based index into array. * @param object The object to set. */ public void set(int index, COSBase object) { objects.set(index, object); } /** * This will set an object at a specific index. * * @param index zero based index into array. * @param intVal The object to set. */ public void set(int index, int intVal) { objects.set(index, COSInteger.get(intVal)); } /** * This will set an object at a specific index. * * @param index zero based index into array. * @param object The object to set. */ public void set(int index, COSObjectable object) { COSBase base = null; if (object != null) { base = object.getCOSObject(); } objects.set(index, base); } /** * This will get an object from the array. This will dereference the object. * If the object is COSNull then null will be returned. * * @param index The index into the array to get the object. * * @return The object at the requested index. */ public COSBase getObject(int index) { Object obj = objects.get(index); if (obj instanceof COSObject) { obj = ((COSObject) obj).getObject(); } if (obj instanceof COSNull) { obj = null; } return (COSBase) obj; } /** * This will get an object from the array. This will NOT dereference * the COS object. * * @param index The index into the array to get the object. * * @return The object at the requested index. */ public COSBase get(int index) { return objects.get(index); } /** * Get the value of the array as an integer. * * @param index The index into the list. * * @return The value at that index or -1 if does not exist. */ public int getInt(int index) { return getInt(index, -1); } /** * Get the value of the array as an integer, return the default if it does not exist. * * @param index The value of the array. * @param defaultValue The value to return if the value is null. * @return The value at the index or the defaultValue. */ public int getInt(int index, int defaultValue) { int retval = defaultValue; if (index < size()) { Object obj = objects.get(index); if (obj instanceof COSNumber) { retval = ((COSNumber) obj).intValue(); } } return retval; } /** * Set the value in the array as an integer. * * @param index The index into the array. * @param value The value to set. */ public void setInt(int index, int value) { set(index, COSInteger.get(value)); } /** * Set the value in the array as a name. * @param index The index into the array. * @param name The name to set in the array. */ public void setName(int index, String name) { set(index, COSName.getPDFName(name)); } /** * Get the value of the array as a string. * * @param index The index into the array. * @return The name converted to a string or null if it does not exist. */ public String getName(int index) { return getName(index, null); } /** * Get an entry in the array that is expected to be a COSName. * @param index The index into the array. * @param defaultValue The value to return if it is null. * @return The value at the index or defaultValue if none is found. */ public String getName(int index, String defaultValue) { String retval = defaultValue; if (index < size()) { Object obj = objects.get(index); if (obj instanceof COSName) { retval = ((COSName) obj).getName(); } } return retval; } /** * Set the value in the array as a string. * @param index The index into the array. * @param string The string to set in the array. */ public void setString(int index, String string) { if (string != null) { set(index, new COSString(string)); } else { set(index, null); } } /** * Get the value of the array as a string. * * @param index The index into the array. * @return The string or null if it does not exist. */ public String getString(int index) { return getString(index, null); } /** * Get an entry in the array that is expected to be a COSName. * @param index The index into the array. * @param defaultValue The value to return if it is null. * @return The value at the index or defaultValue if none is found. */ public String getString(int index, String defaultValue) { String retval = defaultValue; if (index < size()) { Object obj = objects.get(index); if (obj instanceof COSString) { retval = ((COSString) obj).getString(); } } return retval; } /** * This will get the size of this array. * * @return The number of elements in the array. */ public int size() { return objects.size(); } /** * This will remove an element from the array. * * @param i The index of the object to remove. * * @return The object that was removed. */ public COSBase remove(int i) { return objects.remove(i); } /** * This will remove an element from the array. * * @param o The object to remove. * * @return <code>true</code> if the object was removed, <code>false</code> * otherwise */ public boolean remove(COSBase o) { return objects.remove(o); } /** * This will remove an element from the array. * This method will also remove a reference to the object. * * @param o The object to remove. * @return <code>true</code> if the object was removed, <code>false</code> * otherwise */ public boolean removeObject(COSBase o) { boolean removed = this.remove(o); if (!removed) { for (int i = 0; i < this.size(); i++) { COSBase entry = this.get(i); if (entry instanceof COSObject) { COSObject objEntry = (COSObject) entry; if (objEntry.getObject().equals(o)) { return this.remove(entry); } } } } return removed; } /** * {@inheritDoc} */ public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof COSArray)) { return false; } COSArray toBeCompared = (COSArray) o; if (toBeCompared.size() != size()) { return false; } for (int i = 0; i < size(); i++) { if (!(get(i).equals(toBeCompared.get(i)))) { return false; } } return true; } /** * {@inheritDoc} */ @Override public int hashCode() { return Objects.hash(objects, needToBeUpdated); } /** * {@inheritDoc} */ @Override public String toString() { return "COSArray{" + objects + "}"; } /** * Get access to the list. * * @return an iterator over the array elements */ @Override public Iterator<COSBase> iterator() { return objects.iterator(); } /** * This will return the index of the entry or -1 if it is not found. * * @param object The object to search for. * @return The index of the object or -1. */ public int indexOf(COSBase object) { int retval = -1; for (int i = 0; retval < 0 && i < size(); i++) { if (get(i).equals(object)) { retval = i; } } return retval; } /** * This will return the index of the entry or -1 if it is not found. * This method will also find references to indirect objects. * * @param object The object to search for. * @return The index of the object or -1. */ public int indexOfObject(COSBase object) { int retval = -1; for (int i = 0; retval < 0 && i < this.size(); i++) { COSBase item = this.get(i); if (item.equals(object) || item instanceof COSObject && ((COSObject) item).getObject().equals(object)) { retval = i; break; } } return retval; } /** * This will add null values until the size of the array is at least * as large as the parameter. If the array is already larger than the * parameter then nothing is done. * * @param size The desired size of the array. */ public void growToSize(int size) { growToSize(size, null); } /** * This will add the object until the size of the array is at least * as large as the parameter. If the array is already larger than the * parameter then nothing is done. * * @param size The desired size of the array. * @param object The object to fill the array with. */ public void growToSize(int size, COSBase object) { while (size() < size) { add(object); } } /** * visitor pattern double dispatch method. * * @param visitor The object to notify when visiting this object. * @return any object, depending on the visitor implementation, or null * @throws IOException If an error occurs while visiting this object. */ @Override public Object accept(ICOSVisitor visitor) throws IOException { return visitor.visitFromArray(this); } @Override public boolean isNeedToBeUpdated() { return needToBeUpdated; } /** * {@inheritDoc} *<p> * Although the state is set, it has no effect on COSWriter behavior because arrays are always * written as direct object. If an array is to be part of an incremental save, then the method * should be called for its holding dictionary. * * @param flag */ @Override public void setNeedToBeUpdated(boolean flag) { needToBeUpdated = flag; } /** * This will take an COSArray of numbers and convert it to a float[]. * * @return This COSArray as an array of float numbers. */ public float[] toFloatArray() { float[] retval = new float[size()]; for (int i = 0; i < size(); i++) { COSBase base = getObject(i); retval[i] = base instanceof COSNumber ? ((COSNumber) base).floatValue() : 0; } return retval; } /** * Clear the current contents of the COSArray and set it with the float[]. * * @param value The new value of the float array. */ public void setFloatArray(float[] value) { this.clear(); for (float aValue : value) { add(new COSFloat(aValue)); } } /** * Return contents of COSArray as a Java List. * * @return the COSArray as List */ public List<? extends COSBase> toList() { List<COSBase> retList = new ArrayList<>(size()); for (int i = 0; i < size(); i++) { retList.add(get(i)); } return retList; } }