Initial commit from SVN.
This commit is contained in:
@@ -0,0 +1,671 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.io.StreamSupport;
|
||||
import com.common.util.*;
|
||||
import com.foundation.application.Application;
|
||||
import com.foundation.util.xml.DocumentBuilder;
|
||||
import com.foundation.util.xml.IDocument;
|
||||
import com.foundation.util.xml.IElement;
|
||||
import com.foundation.util.xml.INode;
|
||||
import com.foundation.view.JefColor;
|
||||
import com.foundation.view.JefFont;
|
||||
import com.foundation.view.JefGradient;
|
||||
|
||||
/**
|
||||
* This is the base class for the resource service.
|
||||
* The resource service provides the views (and potentially the application) with access to resources built with the application.
|
||||
* Resources cannot be changed during the running of the application, but the current set of resources can be altered based on the application state.
|
||||
* Resources are grouped into ResourcePackage's to allow multiple applications to coexist in one VM under one Application class.
|
||||
* Resources are furthor grouped into ResourceGrouping's to allow for logical organization of resources.
|
||||
* Each ResourceGrouping can have multiple 'versions' which we are calling categories, which contain the same resource names and types, but potentially different values.
|
||||
* A resource is referenced via a ResourceReference or resource URL (a slash delimited string beginning with res:// and containing the package name, then the group name, and finally the resource name).
|
||||
* The resource service can be told which categories are the current categories.
|
||||
* The service then builds the mapping of current resources based on the categories and notifies all listeners that the resource values may have changed.
|
||||
* This system allows for resources to be altered based on language and look and feel for the application.
|
||||
*/
|
||||
public abstract class AbstractResourceService {
|
||||
public static final String RESOURCES_FILE_NAME_POSTFIX = ".res";
|
||||
public static final String GROUP_FILE_NAME_PREFIX = "group.";
|
||||
public static final String RESOURCE_FILE_NAME_PREFIX = "resource.";
|
||||
public static final String PACKAGE_NODE_NAME = "package";
|
||||
public static final String PACKAGE_NAME_ATTRIBUTE = "name";
|
||||
public static final String PACKAGE_PATH_ATTRIBUTE = "path";
|
||||
public static final String PACKAGE_HASH_ATTRIBUTE = "hash";
|
||||
public static final String GROUP_NODE_NAME = "group";
|
||||
public static final String GROUP_NAME_ATTRIBUTE = "name";
|
||||
public static final String CATEGORY_NODE_NAME = "category";
|
||||
public static final String CATEGORY_NAME_ATTRIBUTE = "name";
|
||||
public static final String CATEGORY_PATH_ATTRIBUTE = "path";
|
||||
public static final String CATEGORY_HASH_ATTRIBUTE = "hash";
|
||||
public static final String RESOURCE_NODE_NAME = "resource";
|
||||
public static final String RESOURCE_NAME_ATTRIBUTE = "name";
|
||||
public static final String RESOURCE_TYPE_ATTRIBUTE = "type";
|
||||
public static final String RESOURCE_VALUE_ATTRIBUTE = "value";
|
||||
|
||||
/** The set of Resource instances indexed by their resource URL. These are the resources that the users of the service will access. */
|
||||
private IHashMap currentResources = new LiteHashMap(500);
|
||||
/** The set of current categories that built the current resources set. */
|
||||
private String[] currentCategories = null;
|
||||
/** The set of all registered listeners for changes to the set of current resources. */
|
||||
private LiteHashSet listeners = new LiteHashSet(100);
|
||||
/** The optional loader to be used to retrieve the resource contents given a path. */
|
||||
private IResourceLoader resourceLoader = null;
|
||||
/**
|
||||
* AbstractResourceService constructor.
|
||||
*/
|
||||
public AbstractResourceService(IResourceLoader resourceLoader) {
|
||||
super();
|
||||
this.resourceLoader = resourceLoader;
|
||||
}//AbstractResourceService()//
|
||||
/**
|
||||
* Gets the map of current resources.
|
||||
* @return The mapping of Resource instances indexed by their resource URL.
|
||||
*/
|
||||
protected IHashMap getCurrentResources() {
|
||||
return currentResources;
|
||||
}//getCurrentResources()//
|
||||
/**
|
||||
* Gets the current categories.
|
||||
* <p>Warning: This method makes no attempt to hinder modification of the categories since they are for informational purposes only and changes have no affect on the service.</p>
|
||||
* @return The same exact set of categories that was passed to the set method.
|
||||
*/
|
||||
public String[] getCurrentCategories() {
|
||||
return currentCategories;
|
||||
}//getCurrentCategories()//
|
||||
/**
|
||||
* Sets the categories of resources to be loaded as current.
|
||||
* Each category is a chain of slash delimited category parts which are used to search each grouping of resources for resource values.
|
||||
* @param currentCategories The category strings which are slash delimited category chains.
|
||||
*/
|
||||
public void setCurrentCategories(String[] categories) {
|
||||
LiteList categoryLevels = new LiteList(10, 20);
|
||||
StringBuffer resourceUrlBuffer = new StringBuffer(500);
|
||||
IIterator listenerIterator = listeners.iterator();
|
||||
|
||||
getCurrentResources().removeAll();
|
||||
this.currentCategories = categories;
|
||||
|
||||
/*
|
||||
The following code creates a tree of the categories as such...
|
||||
|
||||
Example:
|
||||
categories = new String[] {"a/b/c", "a/z/y", "t/r"}
|
||||
|
||||
The result will be a list of lists (represented here in sudo code for simplicity and clarity):
|
||||
LiteList { LiteList {"a", "t"}, LiteList {"a/b", "a/z", "t/r"}, LiteList {"a/b/c", "a/z/y"} }
|
||||
|
||||
The lists of lists are to be navigated in this order (last to first for the outer list, first to last for the inner list):
|
||||
"a/b/c"
|
||||
"a/z/y"
|
||||
"a/b"
|
||||
"a/z"
|
||||
"t/r"
|
||||
"a"
|
||||
"t"
|
||||
<default category>
|
||||
*/
|
||||
//Build a tree for the categories using a list of lists. This makes it easy to navigate all the end nodes of the tree back toward the root nodes in the order that they were in the passed string array.//
|
||||
for(int categoryIndex = 0; categoryIndex < categories.length; categoryIndex++) {
|
||||
String category = categories[categoryIndex];
|
||||
int nextSlashIndex;
|
||||
int levelIndex = 0;
|
||||
boolean done = false;
|
||||
|
||||
category = category.replace('\\', '/');
|
||||
nextSlashIndex = category.indexOf('/');
|
||||
|
||||
while(!done) {
|
||||
LiteList level = (LiteList) categoryLevels.get(levelIndex);
|
||||
|
||||
if(level == null) {
|
||||
level = new LiteList(10, 20);
|
||||
categoryLevels.set(levelIndex, level);
|
||||
}//if//
|
||||
|
||||
if(nextSlashIndex != -1) {
|
||||
level.add(category.substring(0, nextSlashIndex));
|
||||
levelIndex++;
|
||||
}//if//
|
||||
else {
|
||||
level.add(category);
|
||||
done = true;
|
||||
}//else//
|
||||
}//while//
|
||||
}//for//
|
||||
|
||||
//Navigate the tree and collect the resources.//
|
||||
for(int outerIndex = categoryLevels.getSize() - 1; outerIndex >= 0; outerIndex--) {
|
||||
LiteList levelCategories = (LiteList) categoryLevels.get(outerIndex);
|
||||
|
||||
for(int innerIndex = 0; innerIndex < levelCategories.getSize(); innerIndex++) {
|
||||
String category = (String) levelCategories.get(innerIndex);
|
||||
|
||||
//Add the resources for the category.//
|
||||
addToCurrentResources(category, resourceUrlBuffer);
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
//Add the default category.//
|
||||
addToCurrentResources("", resourceUrlBuffer);
|
||||
|
||||
//Fire an event notifying all listeners that the resource values may have been altered.//
|
||||
while(listenerIterator.hasNext()) {
|
||||
((IResourceListener) listenerIterator.next()).resourcesChanged();
|
||||
}//while//
|
||||
}//setCurrentCategories()//
|
||||
/**
|
||||
* Adds the resources associated with the given category to the set of current resources.
|
||||
* @param category The category to be searched for.
|
||||
* @param resourceUrlBuffer The reusable buffer for building the resource URL's.
|
||||
*/
|
||||
private void addToCurrentResources(String category, StringBuffer resourceUrlBuffer) {
|
||||
IList resourcePackages = getResourcePackages();
|
||||
|
||||
for(int packageIndex = 0; packageIndex < resourcePackages.getSize(); packageIndex++) {
|
||||
ResourcePackage resourcePackage = (ResourcePackage) resourcePackages.get(packageIndex);
|
||||
//TODO: Find all resource groups that contain this category within the package... add all resources to the group that have not already been filled with a value.
|
||||
IList resourceGroups = getResourceGroups(resourcePackage, category);
|
||||
|
||||
//Iterate over the groups and load the resources.//
|
||||
for(int groupIndex = 0; groupIndex < resourceGroups.getSize(); groupIndex++) {
|
||||
ResourceGroup resourceGroup = (ResourceGroup) resourceGroups.get(groupIndex);
|
||||
ResourceCategory resourceCategory = resourceGroup.getCategory(category);
|
||||
|
||||
//If there is a set of resources for the given category in this group then process them.//
|
||||
if(resourceCategory != null) {
|
||||
IList resources = getResources(resourceCategory);
|
||||
|
||||
//Iterate over the resources and add them the current set of available resources.//
|
||||
for(int resourceIndex = 0; resourceIndex < resources.getSize(); resourceIndex++) {
|
||||
Resource resource = (Resource) resources.get(resourceIndex);
|
||||
String resourceUrl;
|
||||
|
||||
resourceUrlBuffer.setLength(0);
|
||||
resourceUrlBuffer.append(ResourceReference.RESOURCE_URL_PREFIX);
|
||||
resourceUrlBuffer.append(resourcePackage.getName());
|
||||
resourceUrlBuffer.append('/');
|
||||
resourceUrlBuffer.append(resourceGroup.getName());
|
||||
resourceUrlBuffer.append('/');
|
||||
resourceUrlBuffer.append(resource.getName());
|
||||
resourceUrl = resourceUrlBuffer.toString();
|
||||
|
||||
//Only add the resource to the current mapping if one is not already in the mapping.//
|
||||
if(!getCurrentResources().containsKey(resourceUrl)) {
|
||||
getCurrentResources().put(resourceUrl, resource);
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
}//for//
|
||||
}//for//
|
||||
}//addToCurrentResources()//
|
||||
/**
|
||||
* Gets the value for the associated resource reference.
|
||||
* @param resourceReference The reference to the resource.
|
||||
* @return The value for the referenced resource. This will default to null for invalid references.
|
||||
*/
|
||||
public Object getResourceValue(ResourceReference resourceReference) {
|
||||
Resource resource = (Resource) currentResources.get(resourceReference.getResourceUrl());
|
||||
|
||||
return resource != null ? resource.getValue() : null;
|
||||
}//getResourceValue()//
|
||||
/**
|
||||
* Determines whether the resource reference is valid for the current set of resources.
|
||||
* @param resourceReference The reference to the resource.
|
||||
* @return Whether the resource reference can be resolved to a value.
|
||||
*/
|
||||
public boolean isResourceReferenceValid(ResourceReference resourceReference) {
|
||||
return currentResources.containsKey(resourceReference.getResourceUrl());
|
||||
}//isResourceReferenceValid()//
|
||||
/**
|
||||
* Adds a listener to the set of resource change listeners.
|
||||
* @param listener The listener to be notified when changes to the current set of resources is complete.
|
||||
*/
|
||||
public void addListener(IResourceListener listener) {
|
||||
listeners.add(listener);
|
||||
}//addListener()//
|
||||
/**
|
||||
* Removes a listener from the set of resource change listeners.
|
||||
* @param listener The listener to be removed.
|
||||
*/
|
||||
public void removeListener(IResourceListener listener) {
|
||||
listeners.remove(listener);
|
||||
}//removeListener()//
|
||||
/**
|
||||
* Loads the path as an input stream and doesn't single out the compressed resources at the beginning of the file.
|
||||
* <p>Note: This is intended to allow access to the images (and other large resources) stored at the end of the resource file in an uncompressed format.</p>
|
||||
* @param path The path to the resource to be loaded.
|
||||
* @return The input stream containing the data for the resource.
|
||||
* @throws IOException If a problem occurs.
|
||||
*/
|
||||
protected InputStream getRawResourceStream(File path) throws IOException {
|
||||
InputStream result = null;
|
||||
|
||||
if(resourceLoader != null) {
|
||||
result = resourceLoader.load(path);
|
||||
}//if//
|
||||
else {
|
||||
File prefix = getResourcePathPrefix();
|
||||
File file = prefix == null ? path : new File(prefix, path.toString());
|
||||
|
||||
result = new FileInputStream(file);
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//getRawResourceStream()//
|
||||
/**
|
||||
* Loads the path as an input stream over the zipped header. Note that the header contains the resource structure and all small resource values.
|
||||
* @param path The path to the resource to be loaded.
|
||||
* @return The input stream containing the data for the resource.
|
||||
* @throws IOException If a problem occurs.
|
||||
*/
|
||||
protected InputStream getResourceStream(File path) throws IOException {
|
||||
InputStream stream;
|
||||
int headerSize;
|
||||
byte[] bytes;
|
||||
|
||||
if(resourceLoader != null) {
|
||||
stream = resourceLoader.load(path);
|
||||
}//if//
|
||||
else {
|
||||
File prefix = getResourcePathPrefix();
|
||||
File file = prefix == null ? path : new File(prefix, path.toString());
|
||||
|
||||
stream = new FileInputStream(file);
|
||||
}//else//
|
||||
|
||||
headerSize = StreamSupport.readInt(stream);
|
||||
bytes = new byte[headerSize];
|
||||
StreamSupport.readBytes(stream, bytes);
|
||||
stream.close();
|
||||
|
||||
return new GZIPInputStream(new ByteArrayInputStream(bytes));
|
||||
}//getResourceStream()//
|
||||
/**
|
||||
* Gets the prefix for the resource path.
|
||||
* @return The prefix to use with the resource path. This should be null if the path is all that is necessary.
|
||||
*/
|
||||
protected File getResourcePathPrefix() {
|
||||
return null;
|
||||
}//getResourcePathPrefix()//
|
||||
/**
|
||||
* Loads the given file and decompresses it.
|
||||
* @param path The relative location of the resources to be loaded.
|
||||
* @return The decompressed file data.
|
||||
* @throws IOException
|
||||
*/
|
||||
protected byte[] loadResourceValue(File path, long offset, int size) throws IOException {
|
||||
byte[] bytes = new byte[size];
|
||||
InputStream in = null;
|
||||
int count = 0;
|
||||
|
||||
try {
|
||||
in = getRawResourceStream(path);
|
||||
//Skip the compressed XML resource data, and the first four bytes that are the size of the compressed XML resource data, and shift to the correct offset.//
|
||||
in.skip(offset + StreamSupport.readInt(in));
|
||||
|
||||
while(count < bytes.length) {
|
||||
count += in.read(bytes, count, bytes.length - count);
|
||||
}//while//
|
||||
}//try//
|
||||
finally {
|
||||
try {
|
||||
in.close();
|
||||
}//try//
|
||||
catch(Throwable e) {}
|
||||
}//finally//
|
||||
|
||||
return bytes;
|
||||
}//loadResourceFile()//
|
||||
/**
|
||||
* Loads the packages metadata from the stream.
|
||||
* @param resourcePackagesPath The path to the file containing the package metadata.
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
protected IList loadPackages() throws IOException, ClassNotFoundException {
|
||||
String resourcePackagesPath = Application.PACKAGE_RESOURCES_FILE_NAME;
|
||||
LiteList result = new LiteList(20, 100);
|
||||
DocumentBuilder builder = new DocumentBuilder();
|
||||
InputStream in = getResourceStream(new File(resourcePackagesPath));
|
||||
IDocument document = builder.readDocument(in, "UTF8");
|
||||
IIterator iterator = document.getElements().iterator();
|
||||
|
||||
try {
|
||||
in.close();
|
||||
}//try//
|
||||
catch(Throwable e) {}
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
IElement next = (IElement) iterator.next();
|
||||
|
||||
if(next.isNode()) {
|
||||
INode nextNode = (INode) next;
|
||||
|
||||
if(nextNode.getName().equals(PACKAGE_NODE_NAME)) {
|
||||
boolean isValid = true;
|
||||
String name = nextNode.getAttributeValue(PACKAGE_NAME_ATTRIBUTE);
|
||||
String path = nextNode.getAttributeValue(PACKAGE_PATH_ATTRIBUTE);
|
||||
String hash = nextNode.getAttributeValue(PACKAGE_HASH_ATTRIBUTE);
|
||||
|
||||
if((name != null) && (path != null) && (hash != null)) {
|
||||
name = name.trim();
|
||||
path = path.trim();
|
||||
hash = hash.trim();
|
||||
|
||||
if((name.length() > 0) && (path.length() > 0) && (hash.length() > 0)) {
|
||||
result.add(new ResourcePackage(name, path, hash));
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
isValid = false;
|
||||
}//else//
|
||||
|
||||
if(!isValid) {
|
||||
Debug.log("Warning: Invalid package tag in the resource metadata. All package tags must provide valid name, path, and hash attributes.");
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
return result;
|
||||
}//loadPackages()//
|
||||
/**
|
||||
* Loads the packages metadata from the stream.
|
||||
* @param resourceMetadata The package resource metadata stream.
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
protected IList loadGroups(ResourcePackage resourcePackage) throws IOException, ClassNotFoundException {
|
||||
LiteList result = new LiteList(20, 100);
|
||||
DocumentBuilder builder = new DocumentBuilder();
|
||||
InputStream in = getResourceStream(new File(resourcePackage.getPath()));
|
||||
IDocument document = builder.readDocument(in, "UTF8");
|
||||
IIterator groupIterator = document.getElements().iterator();
|
||||
|
||||
try {
|
||||
in.close();
|
||||
}//try//
|
||||
catch(Throwable e) {}
|
||||
|
||||
while(groupIterator.hasNext()) {
|
||||
IElement nextGroup = (IElement) groupIterator.next();
|
||||
|
||||
if(nextGroup.isNode()) {
|
||||
INode nextGroupNode = (INode) nextGroup;
|
||||
|
||||
if(nextGroupNode.getName().equals(GROUP_NODE_NAME)) {
|
||||
boolean isGroupValid = true;
|
||||
String groupName = nextGroupNode.getAttributeValue(GROUP_NAME_ATTRIBUTE);
|
||||
|
||||
if(groupName != null) {
|
||||
groupName = groupName.trim();
|
||||
|
||||
if(groupName.length() > 0) {
|
||||
LiteList categories = new LiteList(20, 100);
|
||||
ResourceCategory[] categoryArray;
|
||||
IIterator categoryIterator = nextGroupNode.getElements().iterator();
|
||||
|
||||
while(categoryIterator.hasNext()) {
|
||||
IElement nextCategory = (IElement) categoryIterator.next();
|
||||
|
||||
if(nextCategory.isNode()) {
|
||||
INode nextCategoryNode = (INode) nextCategory;
|
||||
|
||||
if(nextCategoryNode.getName().equals(CATEGORY_NODE_NAME)) {
|
||||
boolean isCategoryValid = true;
|
||||
String categoryName = nextCategoryNode.getAttributeValue(CATEGORY_NAME_ATTRIBUTE);
|
||||
String categoryPath = nextCategoryNode.getAttributeValue(CATEGORY_PATH_ATTRIBUTE);
|
||||
String categoryHash = nextCategoryNode.getAttributeValue(CATEGORY_HASH_ATTRIBUTE);
|
||||
|
||||
if((categoryName != null) && (categoryPath != null) && (categoryHash != null)) {
|
||||
categoryName = categoryName.trim();
|
||||
categoryPath = categoryPath.trim();
|
||||
categoryHash = categoryHash.trim();
|
||||
|
||||
if((categoryPath.length() > 0) && (categoryHash.length() > 0)) {
|
||||
categories.add(new ResourceCategory(categoryName, categoryPath, categoryHash));
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
isCategoryValid = false;
|
||||
}//else//
|
||||
|
||||
if(!isCategoryValid) {
|
||||
Debug.log("Warning: Invalid category tag in the resource metadata. All category tags must provide valid name, path, and hash attributes.");
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
categoryArray = new ResourceCategory[categories.getSize()];
|
||||
categories.toArray(categoryArray);
|
||||
result.add(new ResourceGroup(groupName, categoryArray));
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
isGroupValid = false;
|
||||
}//else//
|
||||
|
||||
if(!isGroupValid) {
|
||||
Debug.log("Warning: Invalid group tag in the resource metadata. All group tags must provide valid name attribute.");
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
return result;
|
||||
}//loadGroups()//
|
||||
/**
|
||||
* Loads the resources from file. This does not load images though - they are left in the file and lazily loaded later.
|
||||
* <p>TODO: The file should be split up and the images should be loaded from a separate but related file. Right now we load all the image data into memory just to read everything else.</p>
|
||||
* @param resourceMetadata The package resource metadata stream.
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
protected IList loadResources(ResourceCategory resourceCategory) throws IOException, ClassNotFoundException {
|
||||
LiteList result = new LiteList(20, 100);
|
||||
DocumentBuilder builder = new DocumentBuilder();
|
||||
InputStream in = getResourceStream(new File(resourceCategory.getPath()));
|
||||
IDocument document = builder.readDocument(in, "UTF8");
|
||||
IIterator resourceIterator = document.getElements().iterator();
|
||||
|
||||
try {
|
||||
in.close();
|
||||
}//try//
|
||||
catch(Throwable e) {}
|
||||
|
||||
while(resourceIterator.hasNext()) {
|
||||
IElement next = (IElement) resourceIterator.next();
|
||||
|
||||
if(next.isNode()) {
|
||||
INode nextNode = (INode) next;
|
||||
|
||||
if(nextNode.getName().equals(RESOURCE_NODE_NAME)) {
|
||||
boolean isValid = true;
|
||||
String resourceName = nextNode.getAttributeValue(RESOURCE_NAME_ATTRIBUTE);
|
||||
String resourceType = nextNode.getAttributeValue(RESOURCE_TYPE_ATTRIBUTE);
|
||||
String resourceValue = nextNode.getAttributeValue(RESOURCE_VALUE_ATTRIBUTE);
|
||||
|
||||
if((resourceName != null) && (resourceType != null) && (resourceValue != null)) {
|
||||
resourceName = resourceName.trim();
|
||||
resourceType = resourceType.trim();
|
||||
|
||||
if((resourceName.length() > 0) && (resourceType.length() > 0)) {
|
||||
try {
|
||||
int type = Integer.parseInt(resourceType);
|
||||
Object value = resourceValue;
|
||||
Long offset = null;
|
||||
int[] lengths = null;
|
||||
|
||||
switch(type) {
|
||||
case IResource.TYPE_BOOLEAN: {
|
||||
value = Boolean.parseBoolean(resourceValue) ? Boolean.TRUE : Boolean.FALSE;
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_INTEGER: {
|
||||
value = new Integer(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_POSITIVE_INTEGER: {
|
||||
value = new Integer(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_FLOAT: {
|
||||
value = new Float(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_POSITIVE_FLOAT: {
|
||||
value = new Float(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_LONG: {
|
||||
value = new Long(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_POSITIVE_LONG: {
|
||||
value = new Long(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_DOUBLE: {
|
||||
value = new Double(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_POSITIVE_DOUBLE: {
|
||||
value = new Double(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_STRING: {
|
||||
value = resourceValue;
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_FONT: {
|
||||
value = JefFont.getJefFonts(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_IMAGE: {
|
||||
byte[] bytes = StringSupport.fromHexString(resourceValue);
|
||||
|
||||
offset = new Long(StreamSupport.readLong(bytes, 0));
|
||||
lengths = new int[] {StreamSupport.readInt(bytes, 16)};
|
||||
value = null;
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_IMAGES: {
|
||||
byte[] bytes = StringSupport.fromHexString(resourceValue);
|
||||
int byteOffset = 16;
|
||||
int index = 0;
|
||||
|
||||
offset = new Long(StreamSupport.readLong(bytes, 0));
|
||||
lengths = new int[(bytes.length - 16) / 8];
|
||||
|
||||
while(byteOffset < bytes.length) {
|
||||
lengths[index++] = StreamSupport.readInt(bytes, byteOffset);
|
||||
byteOffset += 8;
|
||||
}//while//
|
||||
|
||||
value = null;
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_COLOR: {
|
||||
value = new JefColor(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_GRADIENT: {
|
||||
value = new JefGradient(resourceValue);
|
||||
break;
|
||||
}//case//
|
||||
case IResource.TYPE_CHARACTER: {
|
||||
value = resourceValue.length() > 0 ? new Character(resourceValue.charAt(0)) : null;
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
Debug.log(new RuntimeException("Unexpected IResource type code: " + type));
|
||||
isValid = false;
|
||||
break;
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
if(isValid) {
|
||||
result.add(new Resource(resourceName, new Integer(type), value, resourceCategory.getPath(), offset, lengths, this));
|
||||
}//if//
|
||||
}//try//
|
||||
catch(NumberFormatException e) {
|
||||
isValid = false;
|
||||
}//catch//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
isValid = false;
|
||||
}//else//
|
||||
|
||||
if(!isValid) {
|
||||
Debug.log("Warning: Invalid resource tag. All resource tags must provide valid name, type, and value attributes.");
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
return result;
|
||||
}//loadResources()//
|
||||
/**
|
||||
* Gets the collection of all known resource packages.
|
||||
* @return The set of known resource packages in any order.
|
||||
*/
|
||||
protected abstract IList getResourcePackages();
|
||||
/**
|
||||
* Gets the set of all ResourceGroup instances that have resources under the given category (exact match) and exist in the given resource package.
|
||||
* @param resourcePackage The resource package that the groups must exist in.
|
||||
* @param category The category that the resource group must define resources under.
|
||||
* @return The collection of all matching ResourceGroup instances.
|
||||
*/
|
||||
protected abstract IList getResourceGroups(ResourcePackage resourcePackage, String category);
|
||||
/**
|
||||
* Gets the set of all Resource instances that exist in the given resource package and resource group.
|
||||
* @param resourceCategory The package's group's category whose resources we are looking for.
|
||||
* @return The collection of all matching ResourceGroup instances.
|
||||
*/
|
||||
protected abstract IList getResources(ResourceCategory resourceCategory);
|
||||
/**
|
||||
* Gets the compressed and serialized contents of the resource package file.
|
||||
* @return The compressed and serialized resource package data.
|
||||
*/
|
||||
public abstract byte[] getResourcePackageData();
|
||||
/**
|
||||
* Gets the compressed and serialized contents of the resource group file for the given resource package.
|
||||
* @param resourcePackage The package whose group data is to be retreived.
|
||||
* @return The compressed and serialized resource group data.
|
||||
*/
|
||||
public abstract byte[] getResourceGroupData(ResourcePackage resourcePackage);
|
||||
/**
|
||||
* Gets the compressed and serialized contents of the resource file for the given resource category.
|
||||
* @param resourceCategory The group category whose resource data is to be retreived.
|
||||
* @return The compressed and serialized resource data.
|
||||
*/
|
||||
public abstract byte[] getResourceData(ResourceCategory resourceCategory);
|
||||
/**
|
||||
* Gets the name and hashcode pairs for each code resource required on the client.
|
||||
* @return The array containing names and hashcodes (name, hashcode, name, ...) for the code resources required by the client.
|
||||
*/
|
||||
public abstract String[] getCodeMetadata();
|
||||
/**
|
||||
* Gets the stream of bytes for the requested code resource.
|
||||
* @param name The name of the code resource required by the client.
|
||||
* @return The code resource bytes.
|
||||
*/
|
||||
public abstract byte[] getCodeData(String name);
|
||||
}//AbstractResourceService//
|
||||
47
Foundation/src/com/foundation/view/resource/IResource.java
Normal file
47
Foundation/src/com/foundation/view/resource/IResource.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.util.LiteHashMap;
|
||||
|
||||
/**
|
||||
* Defines some resource constants used by the ResourceValue and ResourceMetadata classes.
|
||||
*/
|
||||
public interface IResource {
|
||||
public static final int TYPE_BOOLEAN = 0;
|
||||
public static final int TYPE_INTEGER = 1;
|
||||
public static final int TYPE_POSITIVE_INTEGER = 2;
|
||||
public static final int TYPE_FLOAT = 3;
|
||||
public static final int TYPE_POSITIVE_FLOAT = 4;
|
||||
public static final int TYPE_LONG = 5;
|
||||
public static final int TYPE_POSITIVE_LONG = 6;
|
||||
public static final int TYPE_DOUBLE = 7;
|
||||
public static final int TYPE_POSITIVE_DOUBLE = 8;
|
||||
public static final int TYPE_STRING = 9;
|
||||
/** A single ImageData instance. */
|
||||
public static final int TYPE_IMAGE = 10;
|
||||
/** Stores an array of JefFont instances (JefFont[]). */
|
||||
public static final int TYPE_FONT = 11;
|
||||
/** Stores a single JefColor instance. */
|
||||
public static final int TYPE_COLOR = 12;
|
||||
public static final int TYPE_CHARACTER = 13;
|
||||
public static final int TYPE_DATE = 14;
|
||||
/** Stores a single JefGradient instance. */
|
||||
public static final int TYPE_GRADIENT = 15;
|
||||
/** Stores an ICollection of ImageData instances. */
|
||||
public static final int TYPE_IMAGES = 16;
|
||||
|
||||
/** Names that map to the type numbers defined in this interface. */
|
||||
public static final String[] TYPE_NAMES = new String[] {
|
||||
"boolean", "integer", "positive-integer", "float", "positive-float", "long", "positive-long", "double", "positive-double",
|
||||
"string", "image", "font", "color", "character", "date", "gradient", "images"
|
||||
};
|
||||
|
||||
public static final LiteHashMap typeNameToNumberMap = new LiteHashMap(TYPE_NAMES.length, LiteHashMap.DEFAULT_LOAD_FACTOR, Comparator.getLogicalComparator(), Comparator.getLogicalComparator(), TYPE_NAMES, null, false);
|
||||
}//IResource//
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2006 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
/**
|
||||
* Identifies a listener to resource changes. Normally this is a view component which populates its properties using a resource.
|
||||
*/
|
||||
public interface IResourceListener {
|
||||
/**
|
||||
* Called when the set of current resources is altered and resources may have changed their values.
|
||||
*/
|
||||
public void resourcesChanged();
|
||||
}//IResourceListener//
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2008,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface IResourceLoader {
|
||||
/**
|
||||
* Loads an input stream for the given path to the resource file.
|
||||
* @param path The path to the resource file (relative).
|
||||
* @return A stream of the contents of the file.
|
||||
*/
|
||||
public InputStream load(File path);
|
||||
}//IResourceLoader//
|
||||
142
Foundation/src/com/foundation/view/resource/Resource.java
Normal file
142
Foundation/src/com/foundation/view/resource/Resource.java
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.foundation.metadata.Attribute;
|
||||
import com.foundation.model.Model;
|
||||
import com.foundation.view.JefImage;
|
||||
|
||||
/**
|
||||
* This class is not immutable. The value may be loaded on demand for large values. This should should not be a problem since the expected uses are within a single threaded context.
|
||||
*/
|
||||
public class Resource extends Model implements IResource {
|
||||
/** The resource's name which is used to reference the resource. */
|
||||
public static final Attribute NAME = registerAttribute(Resource.class, "name");
|
||||
/** The resource type which defines the value's type. */
|
||||
public static final Attribute TYPE = registerAttribute(Resource.class, "type");
|
||||
/** The actual value for the resource. */
|
||||
public static final Attribute VALUE = registerAttribute(Resource.class, "value", AO_LAZY);
|
||||
/** The offset from the start of the file to where the normally uncompressed value starts. This will be null for most resource types, but may be used for very large values (images currently). */
|
||||
public static final Attribute OFFSET = registerAttribute(Resource.class, "offset");
|
||||
/** The byte length for the value(s). This will be null for most resource types, but may be used for very large values. */
|
||||
public static final Attribute LENGTHS = registerAttribute(Resource.class, "lengths");
|
||||
/** The file containing the value. This is only non-null for large values where an index and length are given. */
|
||||
public static final Attribute PATH = registerAttribute(Resource.class, "path");
|
||||
/** The resource service used to load a file to lazy load the value. */
|
||||
private AbstractResourceService resourceService = null;
|
||||
/**
|
||||
* Resource constructor.
|
||||
*/
|
||||
public Resource() {
|
||||
super();
|
||||
}//Resource()//
|
||||
/**
|
||||
* Resource constructor.
|
||||
* @param name The unique (within the resource group) name of the resource.
|
||||
* @param type The resource type which defines the value's type.
|
||||
* @param value The resource's stored value.
|
||||
* @param file The optional file containing the value for types that may have large values.
|
||||
* @param index The optional index to the first byte of extended data for the value for types that may have large values.
|
||||
* @param lengths The optional number of bytes of extended data for types that may have large values.
|
||||
*/
|
||||
public Resource(String name, Integer type, Object value, String path, Long offset, int[] lengths, AbstractResourceService resourceService) {
|
||||
super();
|
||||
setAttributeValue(NAME, name);
|
||||
setAttributeValue(TYPE, type);
|
||||
|
||||
if(offset == null) {
|
||||
setAttributeValue(VALUE, value);
|
||||
}//if//
|
||||
else {
|
||||
this.resourceService = resourceService;
|
||||
setAttributeValue(PATH, path);
|
||||
setAttributeValue(OFFSET, offset);
|
||||
setAttributeValue(LENGTHS, lengths);
|
||||
}//else//
|
||||
}//Resource()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.common.Entity#lazyLoadAttribute(com.foundation.metadata.Attribute)
|
||||
*/
|
||||
protected Object lazyLoadAttribute(Attribute attribute) {
|
||||
Object result = null;
|
||||
|
||||
if(attribute == VALUE) {
|
||||
if((getType().intValue() == IResource.TYPE_IMAGE || getType().intValue() == IResource.TYPE_IMAGES) && (getIsAttributeRealized(OFFSET) && getIsAttributeRealized(LENGTHS))) {
|
||||
try {
|
||||
int[] lengths = getLengths();
|
||||
long offset = getOffset().longValue();
|
||||
|
||||
if(lengths.length > 1) {
|
||||
result = new JefImage[lengths.length];
|
||||
|
||||
for(int index = 0; index < lengths.length; index++) {
|
||||
((JefImage[]) result)[index] = new JefImage(resourceService.loadResourceValue(new File(getPath()), offset, lengths[index]));
|
||||
offset += lengths[index];
|
||||
}//for//
|
||||
}//if//
|
||||
else if(lengths.length == 1) {
|
||||
result = new JefImage(resourceService.loadResourceValue(new File(getPath()), offset, lengths[0]));
|
||||
}//else if//
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
result = super.lazyLoadAttribute(attribute);
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//lazyLoadAttribute()//
|
||||
/**
|
||||
* Gets the resource's name which is used to reference the resource from within the application.
|
||||
* @return The unique (within the resource group) name of the resource.
|
||||
*/
|
||||
public String getName() {
|
||||
return (String) getAttributeValue(NAME);
|
||||
}//getName()//
|
||||
/**
|
||||
* Gets the type code for the resource's value.
|
||||
* @return The resource type which defines the value's type.
|
||||
*/
|
||||
public Integer getType() {
|
||||
return (Integer) getAttributeValue(TYPE);
|
||||
}//getType()//
|
||||
/**
|
||||
* Gets the resource's value.
|
||||
* @return The value for the resource.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return getAttributeValue(VALUE);
|
||||
}//getValue()//
|
||||
/**
|
||||
* Gets the relative path to the system resource containing the resource value.
|
||||
* @return The location of the resource.
|
||||
*/
|
||||
private String getPath() {
|
||||
return (String) getAttributeValue(PATH);
|
||||
}//getFile()//
|
||||
/**
|
||||
* Gets the file offset (from the beginning of the file) of the start of the resource value.
|
||||
* @return The file offset of the value.
|
||||
*/
|
||||
private Long getOffset() {
|
||||
return (Long) getAttributeValue(OFFSET);
|
||||
}//getOffset()//
|
||||
/**
|
||||
* Gets the length of the data in the file containing the resource.
|
||||
* @return The byte length of the data for the resource value.
|
||||
*/
|
||||
private int[] getLengths() {
|
||||
return (int[]) getAttributeValue(LENGTHS);
|
||||
}//getLength()//
|
||||
}//Resource//
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import com.foundation.metadata.Attribute;
|
||||
import com.foundation.model.Model;
|
||||
|
||||
/**
|
||||
* The category divides a group of resources such that a resource can have multiple values for different L&F's and languages.
|
||||
* <p>This class is immutable.</p>
|
||||
*/
|
||||
public class ResourceCategory extends Model {
|
||||
/** The resource category's name. */
|
||||
public static final Attribute NAME = registerAttribute(ResourceCategory.class, "name");
|
||||
/** The path where the compressed group's category data is stored. */
|
||||
public static final Attribute PATH = registerAttribute(ResourceCategory.class, "path");
|
||||
/** The hash of the compressed group's category data. */
|
||||
public static final Attribute HASH = registerAttribute(ResourceCategory.class, "hash");
|
||||
/**
|
||||
* ResourceCategory constructor.
|
||||
* <p>Warning: This constructor is only public to allow for serialization and cloning.</p>
|
||||
*/
|
||||
public ResourceCategory() {
|
||||
super();
|
||||
}//ResourceCategory()//
|
||||
/**
|
||||
* ResourceCategory constructor.
|
||||
* @param name The category name.
|
||||
* @param path The path to the group's category data.
|
||||
* @param hash The hash of the group's category data.
|
||||
*/
|
||||
public ResourceCategory(String name, String path, String hash) {
|
||||
super();
|
||||
setAttributeValue(NAME, name);
|
||||
setAttributeValue(PATH, path);
|
||||
setAttributeValue(HASH, hash);
|
||||
}//ResourceCategory()//
|
||||
/**
|
||||
* Gets the resource package's name which is used to reference the package from within the application.
|
||||
* @return The unique name of the resource package.
|
||||
*/
|
||||
public String getName() {
|
||||
return (String) getAttributeValue(NAME);
|
||||
}//getName()//
|
||||
/**
|
||||
* Gets the path where the compressed resource group data for this category is stored.
|
||||
* @return The resource group's category's data storage path. This is relative to the resource root path held by the resource service.
|
||||
*/
|
||||
public String getPath() {
|
||||
return (String) getAttributeValue(PATH);
|
||||
}//getPath()//
|
||||
/**
|
||||
* Gets the hash of the compressed resource group data for this category.
|
||||
* @return The resource group's category's data hash.
|
||||
*/
|
||||
public String getHash() {
|
||||
return (String) getAttributeValue(HASH);
|
||||
}//getHash()//
|
||||
}//ResourceCategory//
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2006 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import com.foundation.metadata.Attribute;
|
||||
import com.foundation.model.Model;
|
||||
|
||||
/**
|
||||
* A grouping of resources which are bundled together.
|
||||
* The grouping may be defined for multiple application defined categories which allows for rapid switching between languages and L&F's.
|
||||
*/
|
||||
public class ResourceGroup extends Model {
|
||||
/** The resource package's name which is used to reference the package. */
|
||||
public static final Attribute NAME = registerAttribute(ResourceGroup.class, "name");
|
||||
/** The categories that define data for this group. */
|
||||
public static final Attribute CATEGORIES = registerAttribute(ResourceGroup.class, "categories");
|
||||
/**
|
||||
* ResourceGroup constructor.
|
||||
*/
|
||||
public ResourceGroup() {
|
||||
super();
|
||||
}//ResourceGroup()//
|
||||
/**
|
||||
* ResourceGroup constructor.
|
||||
* @param name The unique name of the resource group.
|
||||
* @param categories The categories that define data for this group.
|
||||
*/
|
||||
public ResourceGroup(String name, ResourceCategory[] categories) {
|
||||
super();
|
||||
setAttributeValue(NAME, name);
|
||||
setAttributeValue(CATEGORIES, categories);
|
||||
}//ResourceGroup()//
|
||||
/**
|
||||
* Gets the resource group's name which is used to reference the resource from within the application.
|
||||
* @return The unique name of the resource group.
|
||||
*/
|
||||
public String getName() {
|
||||
return (String) getAttributeValue(NAME);
|
||||
}//getName()//
|
||||
/**
|
||||
* Gets the set of all categories defined for this group.
|
||||
* @return The category metadata for the categories defined for this resource group.
|
||||
*/
|
||||
public ResourceCategory[] getCategories() {
|
||||
return (ResourceCategory[]) getAttributeValue(CATEGORIES);
|
||||
}//getCategories()//
|
||||
/**
|
||||
* Gets the category metadata for the category name.
|
||||
* @param category The name of the category to find under this resource group.
|
||||
* @return The category that matches the given category name.
|
||||
*/
|
||||
public ResourceCategory getCategory(String category) {
|
||||
ResourceCategory[] categories = getCategories();
|
||||
ResourceCategory result = null;
|
||||
|
||||
for(int index = 0; (result == null) && (index < categories.length); index++) {
|
||||
if(categories[index].getName().equals(category)) {
|
||||
result = categories[index];
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
return result;
|
||||
}//getCategory()//
|
||||
}//ResourceGroup//
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import com.common.io.*;
|
||||
|
||||
/*
|
||||
* Describes a grouping of resources in an application.
|
||||
* <p>Note: This metadata is not sent to remote clients, it is purely used for setting up the resource structure, determining when to send resources, and for tools that will allow resources to be initialized.</p>
|
||||
*/
|
||||
public class ResourceGroupMetadata {
|
||||
/** The resource group's name which is used to reference the resource. */
|
||||
private String name = null;
|
||||
/** The description of the resource group. */
|
||||
private String description = null;
|
||||
/** Whether the resource group will be cached for remote clients. */
|
||||
private boolean isCached = false;
|
||||
/**
|
||||
* ResourceGroupMetadata constructor.
|
||||
*/
|
||||
public ResourceGroupMetadata() {
|
||||
super();
|
||||
}//ResourceGroupMetadata()//
|
||||
/**
|
||||
* ResourceGroupMetadata constructor.
|
||||
* @param name The unique name of the resource group.
|
||||
* @param description The human readable description which gives an indication of the resource group's usage.
|
||||
* @param isCached Whether the resource group will be cached.
|
||||
*/
|
||||
public ResourceGroupMetadata(String name, String description, boolean isCached) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.isCached = isCached;
|
||||
}//ResourceGroupMetadata()//
|
||||
/**
|
||||
* Gets the resource group's name which is used to reference the resource from within the application.
|
||||
* @return The unique name of the resource group.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}//getName()//
|
||||
/**
|
||||
* Gets the description for the resource group.
|
||||
* @return The human readable description which gives an indication of the resource group's usage.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}//getDescription()//
|
||||
/**
|
||||
* Determines whether the resource may be cached for remote clients.
|
||||
* @return Whether the resource group should be cached.
|
||||
*/
|
||||
public boolean isCached() {
|
||||
return isCached;
|
||||
}//isCached()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IExternalizable#readExternal(com.common.io.IObjectInputStream)
|
||||
*/
|
||||
public void readExternal(IObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
/*byte version = */in.readByte();
|
||||
|
||||
name = (String) in.readObject();
|
||||
description = (String) in.readObject();
|
||||
isCached = in.readBoolean();
|
||||
}//readExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IExternalizable#writeExternal(com.common.io.IObjectOutputStream)
|
||||
*/
|
||||
public void writeExternal(IObjectOutputStream out) throws IOException {
|
||||
out.writeByte(0);
|
||||
out.writeObject(name);
|
||||
out.writeObject(description);
|
||||
out.writeBoolean(isCached);
|
||||
}//writeExternal()//
|
||||
}//ResourceGroupMetadata//
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2006 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import com.common.io.*;
|
||||
|
||||
/*
|
||||
* Describes a single resource in an application.
|
||||
* <p>Note: This metadata is not sent to remote clients, it is purely used for setting up the resource structure, determining when to send resources, and for tools that will allow resources to be initialized.</p>
|
||||
*/
|
||||
public class ResourceMetadata implements IExternalizable, IResource {
|
||||
/** The resource's name which is used to reference the resource. */
|
||||
private String name = null;
|
||||
/** The description of the resource. */
|
||||
private String description = null;
|
||||
/** The resource value's type. */
|
||||
private int type = TYPE_STRING;
|
||||
/**
|
||||
* ResourceMetadata constructor.
|
||||
*/
|
||||
public ResourceMetadata() {
|
||||
super();
|
||||
}//ResourceMetadata()//
|
||||
/**
|
||||
* ResourceMetadata constructor.
|
||||
* @param name The unique (within the resource group) name of the resource.
|
||||
* @param description The human readable description which gives an indication of the resource's usage.
|
||||
* @param type The resource value's type which must be one of the type constants defined by this class.
|
||||
*/
|
||||
public ResourceMetadata(String name, String description, int type) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
}//ResourceMetadata()//
|
||||
/**
|
||||
* Gets the resource's name which is used to reference the resource from within the application.
|
||||
* @return The unique (within the resource group) name of the resource.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}//getName()//
|
||||
/**
|
||||
* Gets the description for the resource.
|
||||
* @return The human readable description which gives an indication of the resource's usage.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}//getDescription()//
|
||||
/**
|
||||
* Gets the type of the resource value.
|
||||
* @return The resource value's type which will be one of the type constants defined by this class.
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}//getType()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IExternalizable#readExternal(com.common.io.IObjectInputStream)
|
||||
*/
|
||||
public Object readExternal(IObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
/*byte version = */in.readByte();
|
||||
|
||||
name = (String) in.readObject();
|
||||
description = (String) in.readObject();
|
||||
type = in.readInt();
|
||||
|
||||
return null;
|
||||
}//readExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.io.IExternalizable#writeExternal(com.common.io.IObjectOutputStream)
|
||||
*/
|
||||
public void writeExternal(IObjectOutputStream out) throws IOException {
|
||||
out.writeByte(0);
|
||||
out.writeObject(name);
|
||||
out.writeObject(description);
|
||||
out.writeInt(type);
|
||||
}//writeExternal()//
|
||||
}//ResourceMetadata//
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import com.foundation.metadata.Attribute;
|
||||
import com.foundation.model.Model;
|
||||
|
||||
/**
|
||||
* Represents a package of resources organized by groupings and categories.
|
||||
* A package contains a set of groupings which can have different resource values based on the selected category.
|
||||
* This allows for L&F and language settings to change which resources are used for each grouping.
|
||||
* <p>This class is immutable.</p>
|
||||
*/
|
||||
public class ResourcePackage extends Model {
|
||||
/** The resource package's name which is used to reference the package. */
|
||||
public static final Attribute NAME = registerAttribute(ResourcePackage.class, "name");
|
||||
/** The path where the compressed package data is stored. */
|
||||
public static final Attribute PATH = registerAttribute(ResourcePackage.class, "path");
|
||||
/** The hash of the compressed package data as a hex string. */
|
||||
public static final Attribute HASH = registerAttribute(ResourcePackage.class, "hash");
|
||||
/**
|
||||
* ResourcePackage constructor.
|
||||
* <p>Warning: This constructor is only public to allow for serialization and cloning.</p>
|
||||
*/
|
||||
public ResourcePackage() {
|
||||
super();
|
||||
}//ResourcePackage()//
|
||||
/**
|
||||
* ResourcePackage constructor.
|
||||
* @param name The package name.
|
||||
* @param path The path to the package data.
|
||||
* @param hash The hash of the package data.
|
||||
*/
|
||||
public ResourcePackage(String name, String path, String hash) {
|
||||
super();
|
||||
setAttributeValue(NAME, name);
|
||||
setAttributeValue(PATH, path);
|
||||
setAttributeValue(HASH, hash);
|
||||
}//ResourcePackage()//
|
||||
/**
|
||||
* Gets the resource package's name which is used to reference the package from within the application.
|
||||
* @return The unique name of the resource package.
|
||||
*/
|
||||
public String getName() {
|
||||
return (String) getAttributeValue(NAME);
|
||||
}//getName()//
|
||||
/**
|
||||
* Gets the path where the compressed resource package data is stored.
|
||||
* @return The resource package's data storage path. This is relative to the resource root path held by the resource service.
|
||||
*/
|
||||
public String getPath() {
|
||||
return (String) getAttributeValue(PATH);
|
||||
}//getPath()//
|
||||
/**
|
||||
* Gets the hash of the compressed resource package data.
|
||||
* @return The resource package's data hash.
|
||||
*/
|
||||
public String getHash() {
|
||||
return (String) getAttributeValue(HASH);
|
||||
}//getHash()//
|
||||
}//ResourcePackage//
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2006,2007 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
/*
|
||||
* Encapsulates a reference to a resource which resides in a group in a package.
|
||||
*/
|
||||
public class ResourceReference implements Externalizable, Cloneable {
|
||||
/** The case insensitive prefix for a resource url. */
|
||||
public static final String RESOURCE_URL_PREFIX = "res://";
|
||||
public static final String RESOURCE_URL_PREFIX_ALT = "res:\\\\";
|
||||
|
||||
private String resourceUrl = null;
|
||||
private String packageName = null;
|
||||
private String groupName = null;
|
||||
private String resourceName = null;
|
||||
/**
|
||||
* JefResourceReference constructor.
|
||||
* <p>Warning: This constructor provided for serialization and cloning only.</p>
|
||||
*/
|
||||
public ResourceReference() {
|
||||
super();
|
||||
}//JefResourceReference()//
|
||||
/**
|
||||
* JefResourceReference constructor.
|
||||
* @param resourceUrl The URL of the resource being referenced.
|
||||
*/
|
||||
public ResourceReference(String resourceUrl) {
|
||||
super();
|
||||
this.resourceUrl = resourceUrl;
|
||||
|
||||
if(isResourceUrl(resourceUrl)) {
|
||||
resourceUrl = resourceUrl.replace('\\', '/').substring(RESOURCE_URL_PREFIX.length());
|
||||
int packageGroupSeparator = resourceUrl.indexOf('/');
|
||||
int groupResourceSeparator = resourceUrl.indexOf('/', packageGroupSeparator + 1);
|
||||
|
||||
packageName = resourceUrl.substring(0, packageGroupSeparator);
|
||||
groupName = resourceUrl.substring(packageGroupSeparator + 1, groupResourceSeparator);
|
||||
resourceName = resourceUrl.substring(groupResourceSeparator + 1);
|
||||
}//if//
|
||||
else {
|
||||
throw new RuntimeException("Invalid resource URL: " + resourceUrl);
|
||||
}//else//
|
||||
}//JefResourceReference()//
|
||||
/**
|
||||
* Determines whether the given potential resource URL is infact a valid resource URL.
|
||||
* @param resourceUrl The potential resource url.
|
||||
* @return Whether the passed potential resource URL checked out as a valid resource URL.
|
||||
*/
|
||||
public static boolean isResourceUrl(String resourceUrl) {
|
||||
boolean result = false;
|
||||
|
||||
if(resourceUrl != null) {
|
||||
boolean hasPrefix = (resourceUrl.length() >= RESOURCE_URL_PREFIX.length()) && (resourceUrl.substring(0, RESOURCE_URL_PREFIX.length()).equalsIgnoreCase(RESOURCE_URL_PREFIX));
|
||||
boolean hasPrefixAlt = (resourceUrl.length() >= RESOURCE_URL_PREFIX_ALT.length()) && (resourceUrl.substring(0, RESOURCE_URL_PREFIX_ALT.length()).equalsIgnoreCase(RESOURCE_URL_PREFIX_ALT));
|
||||
|
||||
if(hasPrefix || hasPrefixAlt) {
|
||||
int slashCount = 0;
|
||||
int lastSlashIndex = -1;
|
||||
|
||||
result = true;
|
||||
resourceUrl = hasPrefix ? resourceUrl.substring(RESOURCE_URL_PREFIX.length()) : resourceUrl.substring(RESOURCE_URL_PREFIX_ALT.length());
|
||||
|
||||
//Iterate over the characters counting slashes and ensuring they are not sequential.//
|
||||
for(int characterIndex = 0; (result) && (characterIndex < resourceUrl.length()); characterIndex++) {
|
||||
if((resourceUrl.charAt(characterIndex) == '\\') || (resourceUrl.charAt(characterIndex) == '/')) {
|
||||
if(lastSlashIndex == characterIndex - 1) {
|
||||
result = false;
|
||||
}//if//
|
||||
else {
|
||||
slashCount++;
|
||||
lastSlashIndex = characterIndex;
|
||||
}//else//
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
//Make sure there were only two dividing slashes and the last slash is not at the very end since there should only be three parts to a resource URL (package, group, resource).//
|
||||
if(result) {
|
||||
result = lastSlashIndex != resourceUrl.length() && slashCount == 2;
|
||||
}//if//
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//isResourceUrl()//
|
||||
/**
|
||||
* Gets the name of the resource package being referenced.
|
||||
* @return The referenced resource's package name.
|
||||
*/
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}//getPackageName()//
|
||||
/**
|
||||
* Gets the name of the resource group being referenced.
|
||||
* @return The referenced resource's group name.
|
||||
*/
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}//getGroupName()//
|
||||
/**
|
||||
* Gets the name of the resource being referenced.
|
||||
* @return The referenced resource's name.
|
||||
*/
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}//getResourceName()//
|
||||
/**
|
||||
* Gets the full URL of the resource being referenced.
|
||||
* @return The referenced resource's full URL.
|
||||
*/
|
||||
public String getResourceUrl() {
|
||||
return resourceUrl;
|
||||
}//getResourceUrl()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
in.readByte();
|
||||
packageName = in.readUTF();
|
||||
groupName = in.readUTF();
|
||||
resourceName = in.readUTF();
|
||||
resourceUrl = in.readUTF();
|
||||
}//readExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeByte(0);
|
||||
out.writeUTF(packageName);
|
||||
out.writeUTF(groupName);
|
||||
out.writeUTF(resourceName);
|
||||
out.writeUTF(resourceUrl);
|
||||
}//writeExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
ResourceReference clone = (ResourceReference) super.clone();
|
||||
|
||||
clone.packageName = packageName;
|
||||
clone.groupName = groupName;
|
||||
clone.resourceName = resourceName;
|
||||
clone.resourceUrl = resourceUrl;
|
||||
|
||||
return clone;
|
||||
}//clone()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return resourceUrl;
|
||||
}//toString()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
return (object instanceof ResourceReference) && (resourceUrl.equals(((ResourceReference) object).getResourceUrl()));
|
||||
}//equals()//
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return resourceName.hashCode();
|
||||
}//hashCode()//
|
||||
}//JefResourceReference//
|
||||
194
Foundation/src/com/foundation/view/resource/ResourceService.java
Normal file
194
Foundation/src/com/foundation/view/resource/ResourceService.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 2005,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.view.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import com.common.util.*;
|
||||
import com.common.debug.*;
|
||||
import com.common.io.ByteArrayOutputStream;
|
||||
import com.common.io.ObjectOutputStream;
|
||||
import com.common.io.StreamSupport;
|
||||
|
||||
/*
|
||||
* Provides a single point of access for all resources available in a system.
|
||||
* <p>Note: A resource URL is made up of four parts. The first is the prefix 'res:\\' or 'res://', followed by the package name. The third and fourth parts are separated by forward or back slashes and are the group name and resource name respectively. For example: <b>res://Pkg.Name/Grp.Name/Res.Name</b></p>
|
||||
* <p><b>This is a thread safe class.</b></p>
|
||||
*/
|
||||
public class ResourceService extends AbstractResourceService {
|
||||
/** The set of all packages. */
|
||||
private IList resourcePackages;
|
||||
/** A mapping of ILists of ResourceGroups indexed by the ResourcePackage that defines them. */
|
||||
private IHashMap packageToGroupsMap = new LiteHashMap(10);
|
||||
/** The set of all categories defined by the application. */
|
||||
private IHashSet categories = new LiteHashSet(100);
|
||||
/** The relative path where all resource files will be found. */
|
||||
private File resourcePath;
|
||||
/**
|
||||
* ResourceService constructor.
|
||||
* @param resourcePath The relative path to the system resource containing the resource packages.
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public ResourceService(File resourcePath, IResourceLoader resourceLoader) throws IOException, ClassNotFoundException {
|
||||
super(resourceLoader);
|
||||
this.resourcePath = resourcePath;
|
||||
resourcePackages = loadPackages();
|
||||
|
||||
//Setup the package to group mapping and collect the set of all categories.//
|
||||
for(int packageIndex = 0; packageIndex < resourcePackages.getSize(); packageIndex++) {
|
||||
ResourcePackage resourcePackage = (ResourcePackage) resourcePackages.get(packageIndex);
|
||||
IList resourceGroups = loadGroups(resourcePackage);
|
||||
|
||||
packageToGroupsMap.put(resourcePackage, resourceGroups);
|
||||
|
||||
//Collect all the categories defined by this service.//
|
||||
for(int groupIndex = 0; groupIndex < resourceGroups.getSize(); groupIndex++) {
|
||||
ResourceGroup resourceGroup = (ResourceGroup) resourceGroups.get(groupIndex);
|
||||
|
||||
categories.addAll(resourceGroup.getCategories());
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
resourcePackages.isChangeable(false);
|
||||
categories.isChangeable(false);
|
||||
//TODO: Make the mapping immutable as well.
|
||||
}//ResourceService()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getResourcePathPrefix()
|
||||
*/
|
||||
protected File getResourcePathPrefix() {
|
||||
return resourcePath;
|
||||
}//getResourcePathPrefix()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getResourceGroups(com.foundation.view.resource.ResourcePackage, java.lang.String)
|
||||
*/
|
||||
protected IList getResourceGroups(ResourcePackage resourcePackage, String category) {
|
||||
/* This code gets the categories and not the groups...
|
||||
IList groups = (IList) packageToGroupsMap.get(resourcePackage);
|
||||
LiteList result = new LiteList(groups.getSize());
|
||||
|
||||
//Search the groups for categories matching the passed category.//
|
||||
for(int groupIndex = 0; groupIndex < groups.getSize(); groupIndex++) {
|
||||
ResourceGroup group = (ResourceGroup) groups.get(groupIndex);
|
||||
|
||||
for(int categoryIndex = 0; categoryIndex < group.getCategories().length; categoryIndex++) {
|
||||
if(group.getCategories()[categoryIndex].getName().equals(category)) {
|
||||
result.add(group.getCategories()[categoryIndex]);
|
||||
categoryIndex = group.getCategories().length;
|
||||
}//if//
|
||||
}//for//
|
||||
}//for//
|
||||
|
||||
return result;
|
||||
*/
|
||||
return (IList) packageToGroupsMap.get(resourcePackage);
|
||||
}//getResourceGroups()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getResourcePackages()
|
||||
*/
|
||||
protected IList getResourcePackages() {
|
||||
return resourcePackages;
|
||||
}//getResourcePackages()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getResources(com.foundation.view.resource.ResourceCategory)
|
||||
*/
|
||||
protected IList getResources(ResourceCategory resourceCategory) {
|
||||
IList result = null;
|
||||
|
||||
try {
|
||||
result = loadResources(resourceCategory);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//getResources()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getResourcePackageData()
|
||||
*/
|
||||
public byte[] getResourcePackageData() {
|
||||
ByteArrayOutputStream bout = null;
|
||||
GZIPOutputStream zout = null;
|
||||
ObjectOutputStream out = null;
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
bout = new ByteArrayOutputStream(1000, false);
|
||||
zout = new GZIPOutputStream(bout, 1000);
|
||||
out = new ObjectOutputStream(zout, null);
|
||||
out.writeObject(getResourcePackages());
|
||||
out.flush();
|
||||
zout.finish();
|
||||
result = bout.toByteArray();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
finally {
|
||||
try {
|
||||
out.close();
|
||||
zout.close();
|
||||
bout.close();
|
||||
}//try//
|
||||
catch(Throwable e) {}
|
||||
}//finally//
|
||||
|
||||
return result;
|
||||
}//getResourcePackageData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getResourceGroupData(com.foundation.view.resource.ResourcePackage)
|
||||
*/
|
||||
public byte[] getResourceGroupData(ResourcePackage resourcePackage) {
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
InputStream in = getRawResourceStream(new File(resourcePath, resourcePackage.getPath()));
|
||||
|
||||
result = StreamSupport.readBytes(in);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//getResourceGroupData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getResourceData(com.foundation.view.resource.ResourceCategory)
|
||||
*/
|
||||
public byte[] getResourceData(ResourceCategory resourceCategory) {
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
InputStream in = getRawResourceStream(new File(resourcePath, resourceCategory.getPath()));
|
||||
|
||||
result = StreamSupport.readBytes(in);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//getResourceData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getCodeMetadata()
|
||||
*/
|
||||
public String[] getCodeMetadata() {
|
||||
return null;
|
||||
}//getCodeMetadata()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.resource.AbstractResourceService#getCodeData(java.lang.String)
|
||||
*/
|
||||
public byte[] getCodeData(String name) {
|
||||
return null;
|
||||
}//getCodeData()//
|
||||
}//ResourceService//
|
||||
Reference in New Issue
Block a user