/*
* Copyright © 2007-2011 Rebecca G. Bettencourt / Kreative Software
* <p>
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
* <p>
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* <p>
* Alternatively, the contents of this file may be used under the terms
* of the GNU Lesser General Public License (the "LGPL License"), in which
* case the provisions of LGPL License are applicable instead of those
* above. If you wish to allow use of your version of this file only
* under the terms of the LGPL License and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the LGPL License. If you do not delete
* the provisions above, a recipient may use your version of this file
* under either the MPL or the LGPL License.
* @since KSFL 1.0
* @author Rebecca G. Bettencourt, Kreative Software
*/
package com.kreative.rsrc;
import java.util.List;
import java.util.Vector;
import java.util.Set;
import java.util.TreeSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
/**
* The <code>ResourceSearchPath</code> class maintains a list of <code>MacResourceProvider</code>s
* that are searched in order whenever a request for a resource is made.
* Search begins at the element specified by <code>setCurrentMacResourceProvider</code>.
* Methods that write resources or reference resources by index operate solely
* on the current MacResourceProvider. Methods that only read resources by name or ID
* start by looking at the current MacResourceProvider, then keep looking at later elements
* in the list until the resource is found or all elements have been searched.
* @since KSFL 1.0
* @author Rebecca G. Bettencourt, Kreative Software
*/
public class MacResourceSearchPath extends MacResourceProvider implements List<MacResourceProvider> {
private Vector<MacResourceProvider> list = new Vector<MacResourceProvider>();
private int start = 0;
/**
* Adds a Provider to this list, in front of the current Provider.
* The Provider just added becomes the current Provider.
* @param dp the Provider to add to this list.
*/
public void pushProvider(MacResourceProvider dp) {
list.add(start, dp);
}
/**
* Removes the current Provider from this list and returns it.
* The next Provider becomes the current Provider.
* @return the old current Provider.
*/
public MacResourceProvider popProvider() {
return list.remove(start);
}
/**
* Returns the current Provider.
* @return the current Provider.
*/
public MacResourceProvider getCurrentProvider() {
return list.get(start);
}
/**
* Returns the index of the current Provider in this list.
* @return the index of the current Provider in this list.
*/
public int getCurrentProviderIndex() {
return start;
}
/**
* Sets the current Provider, which is the Provider write operations
* work on and searches start on. If the specified Provider is not
* in this list, nothing happens.
* @param dp the new current Provider.
*/
public void setCurrentProvider(MacResourceProvider dp) {
if (contains(dp)) start = indexOf(dp);
}
/**
* Sets the current Provider to the Provider at the specified
* index in this list.
* @param index the index of the new current Provider.
*/
public void setCurrentProvider(int index) {
start = index;
}
/**
* Sets the current Provider to the Provider at the specified
* index in this list.
* @param index the index of the new current Provider.
*/
public void setCurrentProviderIndex(int index) {
start = index;
}
@Override
public boolean isReadOnly() {
return list.get(start).isReadOnly();
}
@Override
public void flush() {
list.get(start).flush();
}
@Override
public void close() {
list.remove(start).close();
}
@Override
public short getResourceMapAttributes() {
return list.get(start).getResourceMapAttributes();
}
@Override
public void setResourceMapAttributes(short attr) {
list.get(start).setResourceMapAttributes(attr);
}
@Override
public boolean add(MacResource r) throws MacResourceAlreadyExistsException {
return list.get(start).add(r);
}
@Override
public boolean contains(int type, short id) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, id)) {
return true;
}
}
return false;
}
@Override
public boolean contains(int type, String name) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, name)) {
return true;
}
}
return false;
}
@Override
public MacResource get(int type, short id) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, id)) {
return list.get(i).get(type, id);
}
}
return null;
}
@Override
public MacResource get(int type, String name) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, name)) {
return list.get(i).get(type, name);
}
}
return null;
}
@Override
public MacResource getAttributes(int type, short id) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, id)) {
return list.get(i).getAttributes(type, id);
}
}
return null;
}
@Override
public MacResource getAttributes(int type, String name) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, name)) {
return list.get(i).getAttributes(type, name);
}
}
return null;
}
@Override
public byte[] getData(int type, short id) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, id)) {
return list.get(i).getData(type, id);
}
}
return null;
}
@Override
public byte[] getData(int type, String name) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, name)) {
return list.get(i).getData(type, name);
}
}
return null;
}
@Override
public boolean remove(int type, short id) {
return list.get(start).remove(type, id);
}
@Override
public boolean remove(int type, String name) {
return list.get(start).remove(type, name);
}
@Override
public boolean set(int type, short id, MacResource r) throws MacResourceAlreadyExistsException {
return list.get(start).set(type, id, r);
}
@Override
public boolean set(int type, String name, MacResource r) throws MacResourceAlreadyExistsException {
return list.get(start).set(type, name, r);
}
@Override
public boolean setAttributes(int type, short id, MacResource r) throws MacResourceAlreadyExistsException {
return list.get(start).setAttributes(type, id, r);
}
@Override
public boolean setAttributes(int type, String name, MacResource r) throws MacResourceAlreadyExistsException {
return list.get(start).setAttributes(type, name, r);
}
@Override
public boolean setData(int type, short id, byte[] data) {
return list.get(start).setData(type, id, data);
}
@Override
public boolean setData(int type, String name, byte[] data) {
return list.get(start).setData(type, name, data);
}
@Override
public int getTypeCount() {
Set<Integer> types = new TreeSet<Integer>();
for (int i = start; i < list.size(); i++) {
for (int type : list.get(i).getTypes()) {
types.add(type);
}
}
return types.size();
}
@Override
public int getType(int index) {
Set<Integer> types = new TreeSet<Integer>();
for (int i = start; i < list.size(); i++) {
for (int type : list.get(i).getTypes()) {
types.add(type);
}
}
int i = 0;
for (Integer type : types) {
if (i == index) return type;
else i++;
}
return 0;
}
@Override
public int[] getTypes() {
Set<Integer> types = new TreeSet<Integer>();
for (int i = start; i < list.size(); i++) {
for (int type : list.get(i).getTypes()) {
types.add(type);
}
}
int[] types2 = new int[types.size()];
int i = 0; for (Integer type : types) types2[i++] = type;
return types2;
}
@Override
public int getResourceCount(int type) {
Set<Short> ids = new TreeSet<Short>();
for (int i = start; i < list.size(); i++) {
for (short id : list.get(i).getIDs(type)) {
ids.add(id);
}
}
return ids.size();
}
@Override
public short getID(int type, int index) {
Set<Short> ids = new TreeSet<Short>();
for (int i = start; i < list.size(); i++) {
for (short id : list.get(i).getIDs(type)) {
ids.add(id);
}
}
int i = 0;
for (Short id : ids) {
if (i == index) return id;
else i++;
}
return 0;
}
@Override
public short[] getIDs(int type) {
Set<Short> ids = new TreeSet<Short>();
for (int i = start; i < list.size(); i++) {
for (short id : list.get(i).getIDs(type)) {
ids.add(id);
}
}
short[] ids2 = new short[ids.size()];
int i = 0; for (Short id : ids) ids2[i++] = id;
return ids2;
}
@Override
public String getName(int type, int index) {
Set<Short> ids = new TreeSet<Short>();
for (int i = start; i < list.size(); i++) {
for (short id : list.get(i).getIDs(type)) {
ids.add(id);
}
}
int i = 0;
for (Short id : ids) {
if (i == index) return getNameFromID(type, id);
else i++;
}
return "";
}
@Override
public String[] getNames(int type) {
Set<Short> ids = new TreeSet<Short>();
for (int i = start; i < list.size(); i++) {
for (short id : list.get(i).getIDs(type)) {
ids.add(id);
}
}
String[] names = new String[ids.size()];
int i = 0; for (Short id : ids) names[i++] = getNameFromID(type, id);
return names;
}
@Override
public short getNextAvailableID(int type, short start) {
while (contains(type, start)) start++;
return start;
}
@Override
public String getNameFromID(int type, short id) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, id)) {
return list.get(i).getNameFromID(type, id);
}
}
return "";
}
@Override
public short getIDFromName(int type, String name) {
for (int i = start; i < list.size(); i++) {
if (list.get(i).contains(type, name)) {
return list.get(i).getIDFromName(type, name);
}
}
return 0;
}
public boolean add(MacResourceProvider o) {
return list.add(o);
}
public void add(int index, MacResourceProvider element) {
list.add(index, element);
}
public boolean addAll(Collection<? extends MacResourceProvider> c) {
return list.addAll(c);
}
public boolean addAll(int index, Collection<? extends MacResourceProvider> c) {
return list.addAll(index, c);
}
public void clear() {
list.clear();
}
public boolean contains(Object elem) {
return list.contains(elem);
}
public boolean containsAll(Collection<?> c) {
return list.containsAll(c);
}
public MacResourceProvider get(int index) {
return list.get(index);
}
public int indexOf(Object elem) {
return list.indexOf(elem);
}
public boolean isEmpty() {
return list.isEmpty();
}
public Iterator<MacResourceProvider> iterator() {
return list.iterator();
}
public int lastIndexOf(Object elem) {
return list.lastIndexOf(elem);
}
public ListIterator<MacResourceProvider> listIterator() {
return list.listIterator();
}
public ListIterator<MacResourceProvider> listIterator(int index) {
return list.listIterator(index);
}
public boolean remove(Object o) {
return list.remove(o);
}
public MacResourceProvider remove(int index) {
return list.remove(index);
}
public boolean removeAll(Collection<?> c) {
return list.removeAll(c);
}
public boolean retainAll(Collection<?> c) {
return list.retainAll(c);
}
public MacResourceProvider set(int index, MacResourceProvider element) {
return list.set(index, element);
}
public int size() {
return list.size();
}
public List<MacResourceProvider> subList(int fromIndex, int toIndex) {
return list.subList(fromIndex, toIndex);
}
public Object[] toArray() {
return list.toArray();
}
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
}