FileDocCategorySizeDatePackage
AppResourceManager.javaAPI DocphoneME MR2 API (J2ME)20557Wed May 02 18:00:46 BST 2007com.sun.j2me.global

AppResourceManager

public class AppResourceManager extends ResourceManager
This class represents a resource manager for accessing application resources.

Fields Summary
private static final String
classname
Class name
public static final byte
TYPE_STRING
Constant for string type resource.
public static final byte
TYPE_BINARY
Constant for binary type resource.
public static final byte
TYPE_END
Constant for end type.
protected ResourceCache
resourceCache
Resource cache.
protected ResourceBundleReader[]
bundleReaders
A resource bundle reader for accessing application resource files.
private String[]
locales
Array of locales that is used for hierarchical matching of resources.
Constructors Summary
public AppResourceManager(String base, String[] locales, ResourceBundleReader[] readers, ResourceCache cache)
Creates a new instance of AppResourceManager. The new instance can be used to get application resources of the given base name and locale. The resource files will be accessed through the given resource bundle readers.

param
base the base name
param
cache cache implementation to speed up resource retrieval
param
locales array of locales to try
param
readers array of readers corresponding to locales



                                                                                      
        
                             
                              

        this.locales = locales;
        setBaseName(base);
        setLocale(locales[0]);
        bundleReaders = readers;
        resourceCache = cache;
    
public AppResourceManager(String base, String[] locales, ResourceBundleReader[] readers)
Constructor for AppResourceManager without caching.

param
base the base name
param
locales array of locales to try
param
readers array of readers corresponding to locales

        this(base, locales, readers, null);
    
Methods Summary
protected java.lang.ObjectcloneResource(java.lang.Object resource)
The method clones resource.

param
resource the resource to clone
return
copy of resource

        if (resource instanceof String) {
            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                               classname + ": " +
                               "returning cloned string resource");
            }
            return new String((String)resource);
        } else if (resource instanceof byte[]) {
            byte[] arry = (byte[])resource;
            byte[] clone = new byte[arry.length];
            System.arraycopy(arry, 0, clone, 0, arry.length);
            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                               classname + ": " +
                               "returning cloned binary resource");
            }
            return clone;
        }
        return resource;
    
protected java.lang.ObjectconvertToResourceType(int resourceID, byte type, int length, ResourceBundleReader reader)
Check if it is known resource type by this manager. Convert it to the expected object. It recognizes {@link #TYPE_STRING} and {@link #TYPE_BINARY} resource types.

param
resourceID the resource identifier
param
type the resource type
param
length the resource length
param
reader resource bundle reader
return
resource as object
throws
IOException if read failed
exception
ResourceException exception is thrown when reading of resource has failed.

        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
            Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                           classname + ": " +
                           "converting resource id = \"" +
                           resourceID +
                           "\" to object" +
                           " type :\"" + type +
                           "\" with reader : " + reader);
        }
        byte[] data = null;
        if (length != 0) {
            data = reader.getRawResourceData(resourceID);
        } else {
            data = new byte[0];
        }
        if (type == TYPE_STRING) {
            try {
                Object o = getUTF8(data);
                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                    Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                                   classname + ": " +
                                   "data converted to utf8 string \"" +
                                   (String)o + "\"");
                }
                return o;
            } catch (IllegalArgumentException iae) {
                throw new IOException("Cannot convert string to UTF8\n" +
                                      iae.getMessage());
            }

        } else if (type == TYPE_BINARY) {
            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                               classname + ": " +
                               "data not converted using pure binary");
            }
            return data;
        }
        return null;
    
public byte[]getData(int id)
Retrieves binary resource in the form of a byte array.

param
id the id of the resource
return
resource as array of bytes
exception
ResourceException is thrown if type of resource isn't binary.

        Object o;
        try {
            o = getResource(id);
        } catch (ResourceException e) {
            int ec = e.getErrorCode();
            String em = e.getMessage();
            if (ec == ResourceException.UNKNOWN_RESOURCE_TYPE) {
                ec = ResourceException.WRONG_RESOURCE_TYPE;
                em = "Resource is not of type BINARY";
            }
            throw new ResourceException(ec, em);
        }
        if (!(o instanceof byte[])) {
            throw new ResourceException(ResourceException.WRONG_RESOURCE_TYPE,
                "Resource is not of type BINARY");
        }
        return (byte[]) o;
    
public java.lang.ObjectgetResource(int id)
Method returns resources of type string and binary as objects. Methods {@link #getData} and {@link #getString} are routed via this method.

Resource cache is used to speed up resource retrieval if ResourceManager was caching.

param
id resource id
return
The resource value
exception
ResourceException is thrown if type of resource isn't binary nor string

        if (id < 0) {
            throw new IllegalArgumentException("Illegal resource ID.");
        }

        int length = 0;
        Object resource = null;
        byte type = (byte) 255;
        ResourceBundleReader reader;
        int hashCode;
        Resource resInCache = null;

        for (int i = 0; i < bundleReaders.length; i++) {
            reader = (ResourceBundleReader) bundleReaders[i];
            try {
                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                    Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                                   classname + ": getResource reader=" +
                                   reader.getResourceName());
                    Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                                   classname + ": " +
                                   " getResource for id \"" + id + "\"");
                }
                if (isCaching()) {
                    // check the cache for resource
                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                        Logging.report(Logging.INFORMATION,
                                       LogChannels.LC_JSR238,
                                       classname + ": Using caching instance.");
                    }
                    hashCode =
                          resourceCache.getHashCodeForResource(getBaseName(),
                                                               locales[i],
                                                               id);
                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                        Logging.report(Logging.INFORMATION,
                                       LogChannels.LC_JSR238,
                                       classname + ": hashCode=" + hashCode);
                    }
                    resInCache = resourceCache.lookup(hashCode);
                    if (resInCache != null) {
                        resource = resInCache.getValue();
                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                            Logging.report(Logging.INFORMATION,
                                           LogChannels.LC_JSR238,
                                           classname +
                                           ": Resource was in cache.");
                        }
                    } else {
                        // caching instance
                        if (reader.isValidResourceID(id)) {
                            type = reader.getResourceType(id);
                            length = reader.getResourceLength(id);
                            resource = convertToResourceType(id, type,
                                                             length, reader);
                            if (resource == null) {
                                if (Logging.REPORT_LEVEL <=
                                    Logging.INFORMATION) {
                                    Logging.report(Logging.INFORMATION,
                                            LogChannels.LC_JSR238,
                                            classname + ": Cannot " +
                                            "convert resource to object");
                                }
                                throw new ResourceException(ResourceException.
                                        UNKNOWN_RESOURCE_TYPE,
                                        "Resource type is unknown.");
                            }
                            resourceCache.addResource(new Resource(hashCode,
                                                                   length,
                                                                   resource));
                        } else {
                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                                Logging.report(Logging.INFORMATION,
                                               LogChannels.LC_JSR238,
                                               classname + ": " +
                                               "Resource id = " + id +
                                               " is NOT valid.");
                            }
                            continue;
                        }
                    }
                } else {
                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                        Logging.report(Logging.INFORMATION,
                                       LogChannels.LC_JSR238,
                                       classname + ": " +
                                       "Using NOTcaching instance.");
                    }
                    if (reader.isValidResourceID(id)) {
                        type = reader.getResourceType(id);
                        length = reader.getResourceLength(id);
                        resource = convertToResourceType(id, type,
                                                               length, reader);
                        if (resource == null) {
                            if (Logging.REPORT_LEVEL <= Logging.WARNING) {
                                Logging.report(Logging.WARNING,
                                               LogChannels.LC_JSR238,
                                               classname + ": Cannot " +
                                               "convert resource to object");
                            }
                            throw new ResourceException(ResourceException.
                                    UNKNOWN_RESOURCE_TYPE,
                                    "Resource type is unknown.");
                        }
                    } else {
                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                            Logging.report(Logging.INFORMATION,
                                           LogChannels.LC_JSR238,
                                           classname + ": " +
                                           "Resource id = " + id +
                                           " is NOT valid.");
                        }
                        continue;
                    }
                }

            } catch (IOException ioe) {
                if (Logging.REPORT_LEVEL <= Logging.WARNING) {
                    Logging.report(Logging.WARNING, LogChannels.LC_JSR238,
                                   classname + ": " +
                                   "IOException: " + ioe.getMessage());
                }
                throw new ResourceException(ResourceException.DATA_ERROR,
                                            "Error reading resource");
            }

            if (resource == null) {
                throw new ResourceException(
                                ResourceException.UNKNOWN_RESOURCE_TYPE,
                                "Unknown resource type \"" + type + "\"");
            } else {
                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                    Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                                   classname + ": " +
                                   "Returning resource object " + resource);
                }
                return cloneResource(resource);
            }
        }// for

        throw new ResourceException(ResourceException.RESOURCE_NOT_FOUND,
                "Invalid resource id " + id + ".");
    
protected bytegetResourceType(int id)
Returns type of the given resource.

param
id The id of the resource
return
The type of resource
throws
ResourceException If resource wasn't found

        byte type;
        AppResourceBundleReader appReader;
        for (int i = 0; i < bundleReaders.length; i++) {
            appReader = (AppResourceBundleReader) bundleReaders[i];
            type = appReader.getResourceType(id);

            if (type == (byte) 0xff) {
                continue;
            } else {
                return type;
            }
        }
        // for
        throw new ResourceException(ResourceException.RESOURCE_NOT_FOUND,
                "Resource not found.");
    
public java.lang.StringgetString(int id)
Retrieves string resource.

param
id the id of the resource
return
resource as string
exception
ResourceException is thrown if type of resource isn't string.

        Object o;
        try {
            o = getResource(id);
        } catch (ResourceException e) {
            int ec = e.getErrorCode();
            String em = e.getMessage();
            if (ec == ResourceException.UNKNOWN_RESOURCE_TYPE) {
                ec = ResourceException.WRONG_RESOURCE_TYPE;
                em = "Resource is not of type STRING";
            }
            throw new ResourceException(ec, em);
        }
        if (!(o instanceof String)) {
            throw new ResourceException(ResourceException.WRONG_RESOURCE_TYPE,
                    "Resource is not of type STRING");
        }
        return (String) o;
    
protected final java.lang.StringgetUTF8(byte[] bytearr)
Conversion of byte array to UTF-8 encoded string.

param
bytearr bytes that make UTF-8 string
return
UTF-8 encoded string

    		StringBuffer sb = new StringBuffer();
    		int count=0;
    		while (count<bytearr.length) {
    		
    		int utf32 = bytearr[count++];
    		
			int numOfBytes;
			if ((utf32 & 0x80) == 0) { sb.append((char) (utf32 & 0x7F));continue;} else
			if ((utf32 & 0xE0) == 0xC0) { numOfBytes = 2; utf32 &= ~0xFFFFFFE0; } else
			if ((utf32 & 0xF0) == 0xE0) { numOfBytes = 3; utf32 &= ~0xFFFFFFF0; } else
			if ((utf32 & 0xF8) == 0xF0) { numOfBytes = 4; utf32 &= ~0xFFFFFFF8; } else 
				throw new IllegalArgumentException("malformed input: around byte " + count);
			
			while (--numOfBytes != 0) {
				if (count==bytearr.length) throw new IllegalArgumentException("malformed input: partial character at end");
				int nextByte = bytearr[count++];
				if ( (nextByte & 0xC0) != 0x80) throw new IllegalArgumentException("malformed input: around byte " + count);
				utf32 <<= 6;
				utf32 += (nextByte & 0x3F);
			}
			
			if (utf32>=0xDC00 && utf32<=0xD800){
				throw new IllegalArgumentException("malformed input: invalid unicode character at pos " + (count-3));
			}
				
			if (utf32>0xFFFF) {
				//handle surrogates:
				int nextChar = 0xDC00 +  (utf32 & 0x3FF);
				utf32 = 0xD800 + ((utf32 - 0x10000) >> 10);
				sb.append((char)utf32);
				sb.append((char)nextChar);
			} else {
				sb.append((char)utf32);
			}
    	}
    		
    	return sb.toString();
    
public booleanisCaching()
Check if ResourceManager implements caching.

return
true if cache is enabled.

        return resourceCache != null;
    
public booleanisValidResourceID(int id)
Check if resource with given id exists.

param
id resource id
return
true if resource exists

        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
            Logging.report(Logging.INFORMATION, LogChannels.LC_JSR238,
                           classname + ": " +
                           "validating resourceId=" + id);
        }

        if (id < 0) {
            throw new IllegalArgumentException("Illegal resource ID.");
        }

        try {
            return (null != getResource(id));
            
        } catch (ResourceException re) {
            return false;
        }