/*
* 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.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.Collection;
import com.kreative.ksfl.KSFLUtilities;
/**
* The <code>ResourceCollection</code> class represents a resource fork as defined by
* the Mac OS Resource Manager in a <code>Map</code>. The Resource Manager was originally
* designed and implemented by Bruce Horn for use in the original
* Macintosh Operating System. It remains today as a feature unique
* to the Mac OS. Other operating systems have the concept of
* resources, but the Mac OS implementation remains unique.
* @since KSFL 1.0
* @author Rebecca G. Bettencourt, Kreative Software
*/
public class MacResourceCollection extends MacResourceProvider implements Map<Integer,Map<Short,MacResource>> {
private Map<Integer,Map<Short,MacResource>> map;
private short attr;
/**
* Creates a new, empty ResourceCollection.
*/
public MacResourceCollection() {
map = new HashMap<Integer,Map<Short,MacResource>>();
attr = 0;
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public synchronized void flush() {
// nothing
}
@Override
public synchronized void close() {
// nothing
}
@Override
public synchronized short getResourceMapAttributes() {
return attr;
}
@Override
public synchronized void setResourceMapAttributes(short attr) {
this.attr = attr;
}
@Override
public synchronized boolean add(MacResource r) throws MacResourceAlreadyExistsException {
if (map.containsKey(r.type) && map.get(r.type).containsKey(r.id)) {
throw new MacResourceAlreadyExistsException();
} else {
if (map.containsKey(r.type)) {
map.get(r.type).put(r.id, r.deepCopy());
} else {
Map<Short,MacResource> nmap = new HashMap<Short,MacResource>();
nmap.put(r.id, r.deepCopy());
map.put(r.type, nmap);
}
return true;
}
}
@Override
public synchronized boolean contains(int type, short id) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
return true;
}
return false;
}
@Override
public synchronized boolean contains(int type, String name) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) return true;
}
}
return false;
}
private MacResource find(int type, short id) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
return map.get(type).get(id);
}
return null;
}
private MacResource find(int type, String name) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) return r;
}
}
return null;
}
@Override
public synchronized MacResource get(int type, short id) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
return map.get(type).get(id).deepCopy();
}
return null;
}
@Override
public synchronized MacResource get(int type, String name) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) return r.deepCopy();
}
}
return null;
}
@Override
public synchronized MacResource getAttributes(int type, short id) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
MacResource r = map.get(type).get(id);
return new MacResource(r.type, r.id, r.getAttributes(), r.name, new byte[0]);
}
return null;
}
@Override
public synchronized MacResource getAttributes(int type, String name) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) {
return new MacResource(r.type, r.id, r.getAttributes(), r.name, new byte[0]);
}
}
}
return null;
}
@Override
public synchronized byte[] getData(int type, short id) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
return KSFLUtilities.copy(map.get(type).get(id).data);
}
return null;
}
@Override
public synchronized byte[] getData(int type, String name) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) return KSFLUtilities.copy(r.data);
}
}
return null;
}
@Override
public synchronized boolean remove(int type, short id) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
map.get(type).remove(id);
if (map.get(type).isEmpty()) {
map.remove(type);
}
return true;
}
return false;
}
@Override
public synchronized boolean remove(int type, String name) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) {
map.get(type).remove(r);
if (map.get(type).isEmpty()) {
map.remove(type);
}
return true;
}
}
}
return false;
}
@Override
public synchronized boolean set(int type, short id, MacResource r) throws MacResourceAlreadyExistsException {
if (!contains(type, id)) {
return false;
} else {
MacResource o = find(type, id);
if ((o.type != r.type || o.id != r.id) && contains(r.type, r.id)) {
throw new MacResourceAlreadyExistsException();
} else {
return remove(type, id) && add(r);
}
}
}
@Override
public synchronized boolean set(int type, String name, MacResource r) throws MacResourceAlreadyExistsException {
if (!contains(type, name)) {
return false;
} else {
MacResource o = find(type, name);
if ((o.type != r.type || o.id != r.id) && contains(r.type, r.id)) {
throw new MacResourceAlreadyExistsException();
} else {
return remove(type, name) && add(r);
}
}
}
@Override
public synchronized boolean setAttributes(int type, short id, MacResource r) throws MacResourceAlreadyExistsException {
if (!contains(type, id)) {
return false;
} else {
MacResource o = find(type, id);
if ((o.type != r.type || o.id != r.id) && contains(r.type, r.id)) {
throw new MacResourceAlreadyExistsException();
} else {
r = r.deepCopy();
r.data = o.data;
return remove(type, id) && add(r);
}
}
}
@Override
public synchronized boolean setAttributes(int type, String name, MacResource r) throws MacResourceAlreadyExistsException {
if (!contains(type, name)) {
return false;
} else {
MacResource o = find(type, name);
if ((o.type != r.type || o.id != r.id) && contains(r.type, r.id)) {
throw new MacResourceAlreadyExistsException();
} else {
r = r.deepCopy();
r.data = o.data;
return remove(type, name) && add(r);
}
}
}
@Override
public synchronized boolean setData(int type, short id, byte[] data) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
map.get(type).get(id).data = KSFLUtilities.copy(data);
return true;
}
return false;
}
@Override
public synchronized boolean setData(int type, String name, byte[] data) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) {
r.data = KSFLUtilities.copy(data);
return true;
}
}
}
return false;
}
@Override
public synchronized int getTypeCount() {
return map.size();
}
@Override
public synchronized int getType(int index) {
return map.keySet().toArray(new Integer[0])[index];
}
@Override
public synchronized int[] getTypes() {
Integer[] types = map.keySet().toArray(new Integer[0]);
int[] types2 = new int[types.length];
for (int i = 0; i < types.length; i++) types2[i] = types[i];
return types2;
}
@Override
public synchronized int getResourceCount(int type) {
if (map.containsKey(type)) {
return map.get(type).size();
}
return 0;
}
@Override
public synchronized short getID(int type, int index) {
if (map.containsKey(type)) {
return map.get(type).keySet().toArray(new Short[0])[index];
}
return 0;
}
@Override
public synchronized short[] getIDs(int type) {
if (map.containsKey(type)) {
Short[] ids = map.get(type).keySet().toArray(new Short[0]);
short[] ids2 = new short[ids.length];
for (int i = 0; i < ids.length; i++) ids2[i] = ids[i];
return ids2;
} else {
return new short[0];
}
}
@Override
public synchronized String getName(int type, int index) {
if (map.containsKey(type)) {
short id = map.get(type).keySet().toArray(new Short[0])[index];
return getNameFromID(type, id);
}
return "";
}
@Override
public synchronized String[] getNames(int type) {
if (map.containsKey(type)) {
Short[] ids = map.get(type).keySet().toArray(new Short[0]);
String[] names = new String[ids.length];
for (int i = 0; i < ids.length; i++) names[i] = getNameFromID(type, ids[i]);
return names;
}
return new String[0];
}
@Override
public synchronized short getNextAvailableID(int type, short start) {
if (map.containsKey(type)) {
while (map.get(type).containsKey(start)) start++;
}
return start;
}
@Override
public synchronized String getNameFromID(int type, short id) {
if (map.containsKey(type) && map.get(type).containsKey(id)) {
return map.get(type).get(id).name;
}
return "";
}
@Override
public synchronized short getIDFromName(int type, String name) {
if (map.containsKey(type)) {
for (MacResource r : map.get(type).values()) {
if (r.name.equals(name)) return r.id;
}
}
return 0;
}
public synchronized void clear() {
map.clear();
}
public synchronized boolean containsKey(Object key) {
return map.containsKey(key);
}
public synchronized boolean containsValue(Object value) {
return map.containsValue(value);
}
public synchronized Set<java.util.Map.Entry<Integer, Map<Short, MacResource>>> entrySet() {
return map.entrySet();
}
public synchronized Map<Short, MacResource> get(Object key) {
return map.get(key);
}
public synchronized boolean isEmpty() {
return map.isEmpty();
}
public synchronized Set<Integer> keySet() {
return map.keySet();
}
public synchronized Map<Short, MacResource> put(Integer key, Map<Short, MacResource> value) {
return map.put(key, value);
}
public synchronized void putAll(Map<? extends Integer, ? extends Map<Short, MacResource>> t) {
map.putAll(t);
}
public synchronized Map<Short, MacResource> remove(Object key) {
return map.remove(key);
}
public synchronized int size() {
return map.size();
}
public synchronized Collection<Map<Short, MacResource>> values() {
return map.values();
}
}