/*
* Copyright 2010 The Ganshane Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package corner.config.services.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.util.StrategyRegistry;
import corner.config.services.ConfigInitable;
import corner.config.services.ConfigurationSource;
/**
* 实现服务配置工厂类.
*
* @author <a href="jun.tsai@ganshane.net">Jun Tsai</a>
* @version $Revision$
* @since 0.0.1
*/
public class ConfigurationSourceImpl implements ConfigurationSource {
private final StrategyRegistry<Resource> registry;
private final Map<Class, Object> cache = CollectionFactory
.newConcurrentMap();
public ConfigurationSourceImpl(Map<Class, Resource> configuration) {
registry = StrategyRegistry.newInstance(Resource.class, configuration);
}
/**
*
* @see corner.config.services.ConfigurationSource#getServiceConfig(java.lang.Class)
*/
@Override
public <T> T getServiceConfig(Class<T> type) {
Defense.notNull(type, "type");
T result = (T) cache.get(type);
if (result == null) {
Resource resource = registry.get(type);
result = createServiceConfigObject(type, resource);
cache.put(type, result);
}
return result;
}
private <T> T createServiceConfigObject(Class<T> type, Resource resource) {
InputStream in;
try {
in = resource.openStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (in == null) {
throw new RuntimeException("The config source[" + resource
+ "] can't be found.");
}
Reader reader = new InputStreamReader(in);
T result = load(reader, type);
if (result instanceof ConfigInitable) {
((ConfigInitable) result).init();
}
return result;
}
/**
* 从一个输入流里加载clazz类型的对象
*
* @param <T>
* @param in 操作完成后,会被关闭
* @param clazz
* @return
* @throws RuntimeException
* 在加载的过程出现异常,将抛出此异常
*/
public static <T> T load(Reader in, Class<T> clazz) {
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller um = context.createUnmarshaller();
return (T) um.unmarshal(in);
} catch (JAXBException e) {
throw new RuntimeException(e);
} finally {
InternalUtils.close(in);
}
}
}