/*
* hgcommons 7
* Hammurapi Group Common Library
* Copyright (C) 2003 Hammurapi Group
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
* e-Mail: support@hammurapi.biz
*/
package biz.hammurapi.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import biz.hammurapi.config.ConfigurationException;
import biz.hammurapi.config.Context;
import biz.hammurapi.config.DomConfigFactory;
import biz.hammurapi.config.RuntimeConfigurationException;
/**
* Utility class which searches class hierarchy for a resource.
* Resource shall be named after class name, profile name is separated from
* class name by ! and locale separated from class name/profile by _.
* @author Pavel Vlasov
* @revision $Revision$
*/
public class ClassResourceLoader {
private Visitable visitable;
private Class clazz;
/**
*
*/
public ClassResourceLoader(Class clazz) {
this.visitable=new ClassHierarchyVisitable(clazz);
this.clazz=clazz;
}
/**
*
* @param profile Profile, can be null
* @param extension Extension, can be null
* @return
*/
public InputStream getResourceAsStream(String profile, String extension) {
return getResourceAsStream(profile, Locale.getDefault(), extension);
}
/**
* @param profile
* @param extension
* @return
*/
public InputStream getResourceAsStream(final String profile, final Locale locale, final String extension) {
final InputStream[] ret={null};
visitable.accept(new Visitor() {
Locale actualLocale = locale==null ? Locale.getDefault() : locale;
public boolean visit(Object target) {
Class currentClass=(Class) target;
for (int i=0; i<4; i++) {
String variant=currentClass.getName().replace('.','/');
if (profile!=null) {
variant+="!"+profile;
}
switch (i) {
case 0:
variant+="_"+actualLocale;
break;
case 1:
variant+="_"+actualLocale.getLanguage();
if (actualLocale.getCountry().length()!=0) {
variant+="_"+actualLocale.getCountry();
}
break;
case 2:
variant+="_"+actualLocale.getLanguage();
break;
case 3:
break;
}
if (extension!=null) {
variant+="."+extension;
}
ret[0]=clazz.getClassLoader().getResourceAsStream(variant);
if (ret[0]!=null) {
return false;
}
}
return true;
}
});
return ret[0];
}
/**
*
* @param profile Profile, can be null
* @param extension Extension, can be null
* @return
*/
public Properties getProperties(String profile, String extension) {
return getProperties(profile, Locale.getDefault(), extension);
}
/**
* @param profile
* @param extension
* @return
*/
public Properties getProperties(final String profile, final Locale locale, final String extension) {
final Properties ret=new Properties();
visitable.accept(new Visitor() {
public boolean visit(Object target) {
Class currentClass=(Class) target;
for (int i=0; i<4; i++) {
String variant=currentClass.getName().replace('.','/');
if (profile!=null) {
variant+=profile;
}
switch (i) {
case 0:
variant+="_"+locale;
break;
case 1:
variant+="_"+locale.getLanguage();
if (locale.getCountry().length()!=0) {
variant+="_"+locale.getCountry();
}
break;
case 2:
variant+="_"+locale.getLanguage();
break;
case 3:
break;
}
if (extension!=null) {
variant+="."+extension;
}
InputStream s=clazz.getClassLoader().getResourceAsStream(variant);
if (s!=null) {
Properties cp=new Properties();
try {
cp.load(s);
Iterator it=cp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry=(Map.Entry) it.next();
if (!ret.containsKey(entry.getKey())) {
ret.setProperty((String) entry.getKey(), (String) entry.getValue());
}
}
} catch (IOException e) {
throw new RuntimeConfigurationException("Cannot load properties from resource "+variant, e);
}
break;
}
}
return true;
}
});
return ret;
}
/**
* @param profile
* @param extension
* @return
*/
public Context getContext(final String profile, Locale locale, final String extension) {
final Locale actualLocale = locale==null ? Locale.getDefault() : locale;
final Collection contexts=new ArrayList();
final DomConfigFactory dcf=new DomConfigFactory();
visitable.accept(new Visitor() {
public boolean visit(Object target) {
Class currentClass=(Class) target;
for (int i=0; i<4; i++) {
String variant=currentClass.getName().replace('.','/');
if (profile!=null) {
variant+=profile;
}
switch (i) {
case 0:
variant+="_"+actualLocale;
break;
case 1:
variant+="_"+actualLocale.getLanguage();
if (actualLocale.getCountry().length()!=0) {
variant+="_"+actualLocale.getCountry();
}
break;
case 2:
variant+="_"+actualLocale.getLanguage();
break;
case 3:
break;
}
if (extension!=null) {
variant+="."+extension;
}
InputStream s=clazz.getClassLoader().getResourceAsStream(variant);
if (s!=null) {
try {
contexts.add(dcf.create(s, null));
} catch (ConfigurationException e) {
throw new RuntimeConfigurationException(e);
} catch (IOException e) {
throw new RuntimeConfigurationException(e);
}
break;
}
}
return true;
}
});
return contexts.isEmpty() ? null : new Context() {
public Object get(String name) {
Iterator it=contexts.iterator();
while (it.hasNext()) {
Object ret=((Context) it.next()).get(name);
if (ret!=null) {
return ret;
}
}
return null;
}
};
}
}
|