/*
* Copyright Terracotta, Inc.
*
* 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 org.ehcache.xml;
import org.ehcache.config.ResourcePool;
import org.ehcache.config.ResourceUnit;
import org.ehcache.config.SizedResourcePool;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.core.config.SizedResourcePoolImpl;
import org.ehcache.xml.exceptions.XmlConfigurationException;
import org.ehcache.xml.model.BaseCacheType;
import org.ehcache.xml.model.CacheLoaderWriterType;
import org.ehcache.xml.model.CacheTemplateType;
import org.ehcache.xml.model.CacheType;
import org.ehcache.xml.model.ConfigType;
import org.ehcache.xml.model.CopierType;
import org.ehcache.xml.model.Disk;
import org.ehcache.xml.model.DiskStoreSettingsType;
import org.ehcache.xml.model.EventFiringType;
import org.ehcache.xml.model.EventOrderingType;
import org.ehcache.xml.model.EventType;
import org.ehcache.xml.model.ExpiryType;
import org.ehcache.xml.model.Heap;
import org.ehcache.xml.model.ListenersType;
import org.ehcache.xml.model.MemoryType;
import org.ehcache.xml.model.ObjectFactory;
import org.ehcache.xml.model.Offheap;
import org.ehcache.xml.model.PersistableMemoryType;
import org.ehcache.xml.model.PersistenceType;
import org.ehcache.xml.model.ResourceType;
import org.ehcache.xml.model.ResourcesType;
import org.ehcache.xml.model.SerializerType;
import org.ehcache.xml.model.ServiceType;
import org.ehcache.xml.model.SizeofType;
import org.ehcache.xml.model.TimeType;
import org.ehcache.spi.service.ServiceConfiguration;
import org.ehcache.spi.service.ServiceCreationConfiguration;
import org.ehcache.core.internal.util.ClassLoading;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.ehcache.xml.model.ThreadPoolReferenceType;
import org.ehcache.xml.model.ThreadPoolsType;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
/**
* Provides support for parsing a cache configuration expressed in XML.
*/
class ConfigurationParser {
private static final Pattern SYSPROP = Pattern.compile("\\$\\{([^}]+)\\}");
private static final SchemaFactory XSD_SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
private static final URL CORE_SCHEMA_URL = XmlConfiguration.class.getResource("/ehcache-core.xsd");
private static final String CORE_SCHEMA_NAMESPACE = "http://www.ehcache.org/v3";
private static final String CORE_SCHEMA_ROOT_ELEMENT = "config";
private static final String CORE_SCHEMA_JAXB_MODEL_PACKAGE = ConfigType.class.getPackage().getName();
private final Map<URI, CacheManagerServiceConfigurationParser<?>> xmlParsers = new HashMap<URI, CacheManagerServiceConfigurationParser<?>>();
private final Map<URI, CacheServiceConfigurationParser<?>> cacheXmlParsers = new HashMap<URI, CacheServiceConfigurationParser<?>>();
private final Unmarshaller unmarshaller;
private final Map<URI, CacheResourceConfigurationParser> resourceXmlParsers = new HashMap<URI, CacheResourceConfigurationParser>();
private final ConfigType config;
static String replaceProperties(String originalValue, final Properties properties) {
Matcher matcher = SYSPROP.matcher(originalValue);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
final String property = matcher.group(1);
final String value = properties.getProperty(property);
if (value == null) {
throw new IllegalStateException(String.format("Replacement for ${%s} not found!", property));
}
matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
}
matcher.appendTail(sb);
final String resolvedValue = sb.toString();
return resolvedValue.equals(originalValue) ? null : resolvedValue;
}
public ConfigurationParser(String xml) throws IOException, SAXException, JAXBException, ParserConfigurationException {
Collection<Source> schemaSources = new ArrayList<Source>();
schemaSources.add(new StreamSource(CORE_SCHEMA_URL.openStream()));
for (CacheManagerServiceConfigurationParser<?> parser : ClassLoading.libraryServiceLoaderFor(CacheManagerServiceConfigurationParser.class)) {
schemaSources.add(parser.getXmlSchema());
xmlParsers.put(parser.getNamespace(), parser);
}
for (CacheServiceConfigurationParser<?> parser : ClassLoading.libraryServiceLoaderFor(CacheServiceConfigurationParser.class)) {
schemaSources.add(parser.getXmlSchema());
cacheXmlParsers.put(parser.getNamespace(), parser);
}
// Parsers for /config/cache/resources extensions
for (CacheResourceConfigurationParser parser : ClassLoading.libraryServiceLoaderFor(CacheResourceConfigurationParser.class)) {
schemaSources.add(parser.getXmlSchema());
resourceXmlParsers.put(parser.getNamespace(), parser);
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setSchema(XSD_SCHEMA_FACTORY.newSchema(schemaSources.toArray(new Source[schemaSources.size()])));
DocumentBuilder domBuilder = factory.newDocumentBuilder();
domBuilder.setErrorHandler(new FatalErrorHandler());
Element dom = domBuilder.parse(xml).getDocumentElement();
substituteSystemProperties(dom);
if (!CORE_SCHEMA_ROOT_ELEMENT.equals(dom.getLocalName()) || !CORE_SCHEMA_NAMESPACE.equals(dom.getNamespaceURI())) {
throw new XmlConfigurationException("Expecting {" + CORE_SCHEMA_NAMESPACE + "}" + CORE_SCHEMA_ROOT_ELEMENT
+ " element; found {" + dom.getNamespaceURI() + "}" + dom.getLocalName());
}
Class<ConfigType> configTypeClass = ConfigType.class;
JAXBContext jc = JAXBContext.newInstance(CORE_SCHEMA_JAXB_MODEL_PACKAGE, configTypeClass.getClassLoader());
this.unmarshaller = jc.createUnmarshaller();
this.config = unmarshaller.unmarshal(dom, configTypeClass).getValue();
}
private void substituteSystemProperties(final Element dom) {
final Properties properties = System.getProperties();
Stack<NodeList> nodeLists = new Stack<NodeList>();
nodeLists.push(dom.getChildNodes());
while (!nodeLists.isEmpty()) {
NodeList nodeList = nodeLists.pop();
for (int i = 0; i < nodeList.getLength(); ++i) {
Node currentNode = nodeList.item(i);
if (currentNode.hasChildNodes()) {
nodeLists.push(currentNode.getChildNodes());
}
final NamedNodeMap attributes = currentNode.getAttributes();
if (attributes != null) {
for (int j = 0; j < attributes.getLength(); ++j) {
final Node attributeNode = attributes.item(j);
final String newValue = replaceProperties(attributeNode.getNodeValue(), properties);
if (newValue != null) {
attributeNode.setNodeValue(newValue);
}
}
}
if (currentNode.getNodeType() == Node.TEXT_NODE) {
final String newValue = replaceProperties(currentNode.getNodeValue(), properties);
if (newValue != null) {
currentNode.setNodeValue(newValue);
}
}
}
}
}
public Iterable<ServiceType> getServiceElements() {
return config.getService();
}
public SerializerType getDefaultSerializers() {
return config.getDefaultSerializers();
}
public CopierType getDefaultCopiers() {
return config.getDefaultCopiers();
}
public PersistenceType getPersistence() {
return config.getPersistence();
}
public ThreadPoolReferenceType getEventDispatch() {
return config.getEventDispatch();
}
public ThreadPoolReferenceType getWriteBehind() {
return config.getWriteBehind();
}
public ThreadPoolReferenceType getDiskStore() {
return config.getDiskStore();
}
public ThreadPoolsType getThreadPools() {
return config.getThreadPools();
}
public SizeOfEngineLimits getHeapStore() {
SizeofType type = config.getHeapStore();
return type == null ? null : new XmlSizeOfEngineLimits(type);
}
public Iterable<CacheDefinition> getCacheElements() {
List<CacheDefinition> cacheCfgs = new ArrayList<CacheDefinition>();
final List<BaseCacheType> cacheOrCacheTemplate = config.getCacheOrCacheTemplate();
for (BaseCacheType baseCacheType : cacheOrCacheTemplate) {
if(baseCacheType instanceof CacheType) {
final CacheType cacheType = (CacheType)baseCacheType;
final BaseCacheType[] sources;
if(cacheType.getUsesTemplate() != null) {
sources = new BaseCacheType[2];
sources[0] = cacheType;
sources[1] = (BaseCacheType) cacheType.getUsesTemplate();
} else {
sources = new BaseCacheType[1];
sources[0] = cacheType;
}
cacheCfgs.add(new CacheDefinition() {
@Override
public String id() {
return cacheType.getAlias();
}
@Override
public String keyType() {
String value = null;
for (BaseCacheType source : sources) {
value = source.getKeyType() != null ? source.getKeyType().getValue() : null;
if (value != null) break;
}
if (value == null) {
for (BaseCacheType source : sources) {
value = JaxbHelper.findDefaultValue(source, "keyType");
if (value != null) break;
}
}
return value;
}
@Override
public String keySerializer() {
String value = null;
for (BaseCacheType source : sources) {
value = source.getKeyType() != null ? source.getKeyType().getSerializer() : null;
if (value != null) break;
}
return value;
}
@Override
public String keyCopier() {
String value = null;
for (BaseCacheType source : sources) {
value = source.getKeyType() != null ? source.getKeyType().getCopier() : null;
if (value != null) break;
}
return value;
}
@Override
public String valueType() {
String value = null;
for (BaseCacheType source : sources) {
value = source.getValueType() != null ? source.getValueType().getValue() : null;
if (value != null) break;
}
if (value == null) {
for (BaseCacheType source : sources) {
value = JaxbHelper.findDefaultValue(source, "valueType");
if (value != null) break;
}
}
return value;
}
@Override
public String valueSerializer() {
String value = null;
for (BaseCacheType source : sources) {
value = source.getValueType() != null ? source.getValueType().getSerializer() : null;
if (value != null) break;
}
return value;
}
@Override
public String valueCopier() {
String value = null;
for (BaseCacheType source : sources) {
value = source.getValueType() != null ? source.getValueType().getCopier() : null;
if (value != null) break;
}
return value;
}
@Override
public String evictionAdvisor() {
String value = null;
for (BaseCacheType source : sources) {
value = source.getEvictionAdvisor();
if (value != null) break;
}
return value;
}
@Override
public Expiry expiry() {
ExpiryType value = null;
for (BaseCacheType source : sources) {
value = source.getExpiry();
if (value != null) break;
}
if (value != null) {
return new XmlExpiry(value);
} else {
return null;
}
}
@Override
public String loaderWriter() {
String configClass = null;
for (BaseCacheType source : sources) {
final CacheLoaderWriterType loaderWriter = source.getLoaderWriter();
if (loaderWriter != null) {
configClass = loaderWriter.getClazz();
break;
}
}
return configClass;
}
@Override
public ListenersConfig listenersConfig() {
ListenersType base = null;
ArrayList<ListenersType> additionals = new ArrayList<ListenersType>();
for (BaseCacheType source : sources) {
if (source.getListeners() != null) {
if (base == null) {
base = source.getListeners();
} else {
additionals.add(source.getListeners());
}
}
}
return base != null ? new XmlListenersConfig(base, additionals.toArray(new ListenersType[0])) : null;
}
@Override
public Iterable<ServiceConfiguration<?>> serviceConfigs() {
Map<Class<? extends ServiceConfiguration>, ServiceConfiguration<?>> configsMap =
new HashMap<Class<? extends ServiceConfiguration>, ServiceConfiguration<?>>();
for (BaseCacheType source : sources) {
for (Element child : source.getServiceConfiguration()) {
ServiceConfiguration<?> serviceConfiguration = parseCacheExtension(child);
if (!configsMap.containsKey(serviceConfiguration.getClass())) {
configsMap.put(serviceConfiguration.getClass(), serviceConfiguration);
}
}
}
return configsMap.values();
}
@Override
public Collection<ResourcePool> resourcePools() {
for (BaseCacheType source : sources) {
Heap heapResource = source.getHeap();
if (heapResource != null) {
return singleton(parseResource(heapResource));
} else {
ResourcesType resources = source.getResources();
if (resources != null) {
return parseResources(resources);
}
}
}
return emptySet();
}
@Override
public WriteBehind writeBehind() {
for (BaseCacheType source : sources) {
final CacheLoaderWriterType loaderWriter = source.getLoaderWriter();
final CacheLoaderWriterType.WriteBehind writebehind = loaderWriter != null ? loaderWriter.getWriteBehind() : null;
if (writebehind != null) {
return new XmlWriteBehind(writebehind);
}
}
return null;
}
@Override
public DiskStoreSettings diskStoreSettings() {
DiskStoreSettingsType value = null;
for (BaseCacheType source : sources) {
value = source.getDiskStoreSettings();
if (value != null) break;
}
if (value != null) {
return new XmlDiskStoreSettings(value);
} else {
return null;
}
}
@Override
public SizeOfEngineLimits heapStoreSettings() {
SizeofType sizeofType = null;
for (BaseCacheType source : sources) {
sizeofType = source.getHeapStoreSettings();
if (sizeofType != null) break;
}
return sizeofType != null ? new XmlSizeOfEngineLimits(sizeofType) : null;
}
});
}
}
return Collections.unmodifiableList(cacheCfgs);
}
public Map<String, CacheTemplate> getTemplates() {
final Map<String, CacheTemplate> templates = new HashMap<String, CacheTemplate>();
final List<BaseCacheType> cacheOrCacheTemplate = config.getCacheOrCacheTemplate();
for (BaseCacheType baseCacheType : cacheOrCacheTemplate) {
if (baseCacheType instanceof CacheTemplateType) {
final CacheTemplateType cacheTemplate = (CacheTemplateType)baseCacheType;
templates.put(cacheTemplate.getName(), new CacheTemplate() {
@Override
public String keyType() {
String keyType = cacheTemplate.getKeyType() != null ? cacheTemplate.getKeyType().getValue() : null;
if (keyType == null) {
keyType = JaxbHelper.findDefaultValue(cacheTemplate, "keyType");
}
return keyType;
}
@Override
public String keySerializer() {
return cacheTemplate.getKeyType() != null ? cacheTemplate.getKeyType().getSerializer() : null;
}
@Override
public String keyCopier() {
return cacheTemplate.getKeyType() != null ? cacheTemplate.getKeyType().getCopier() : null;
}
@Override
public String valueType() {
String valueType = cacheTemplate.getValueType() != null ? cacheTemplate.getValueType().getValue() : null;
if (valueType == null) {
valueType = JaxbHelper.findDefaultValue(cacheTemplate, "valueType");
}
return valueType;
}
@Override
public String valueSerializer() {
return cacheTemplate.getValueType() != null ? cacheTemplate.getValueType().getSerializer() : null;
}
@Override
public String valueCopier() {
return cacheTemplate.getValueType() != null ? cacheTemplate.getValueType().getCopier() : null;
}
@Override
public String evictionAdvisor() {
return cacheTemplate.getEvictionAdvisor();
}
@Override
public Expiry expiry() {
ExpiryType cacheTemplateExpiry = cacheTemplate.getExpiry();
if (cacheTemplateExpiry != null) {
return new XmlExpiry(cacheTemplateExpiry);
} else {
return null;
}
}
@Override
public ListenersConfig listenersConfig() {
final ListenersType integration = cacheTemplate.getListeners();
return integration != null ? new XmlListenersConfig(integration) : null;
}
@Override
public String loaderWriter() {
final CacheLoaderWriterType loaderWriter = cacheTemplate.getLoaderWriter();
return loaderWriter != null ? loaderWriter.getClazz() : null;
}
@Override
public Iterable<ServiceConfiguration<?>> serviceConfigs() {
Collection<ServiceConfiguration<?>> configs = new ArrayList<ServiceConfiguration<?>>();
for (Element child : cacheTemplate.getServiceConfiguration()) {
configs.add(parseCacheExtension(child));
}
return configs;
}
@Override
public Collection<ResourcePool> resourcePools() {
Heap heapResource = cacheTemplate.getHeap();
if (heapResource != null) {
return singleton(parseResource(heapResource));
} else {
ResourcesType resources = cacheTemplate.getResources();
if (resources != null) {
return parseResources(resources);
}
}
return emptySet();
}
@Override
public WriteBehind writeBehind() {
final CacheLoaderWriterType loaderWriter = cacheTemplate.getLoaderWriter();
final CacheLoaderWriterType.WriteBehind writebehind = loaderWriter != null ? loaderWriter.getWriteBehind(): null;
return writebehind != null ? new XmlWriteBehind(writebehind) : null;
}
@Override
public DiskStoreSettings diskStoreSettings() {
final DiskStoreSettingsType diskStoreSettings = cacheTemplate.getDiskStoreSettings();
return diskStoreSettings == null ? null : new XmlDiskStoreSettings(diskStoreSettings);
}
@Override
public SizeOfEngineLimits heapStoreSettings() {
SizeofType type = cacheTemplate.getHeapStoreSettings();
return type == null ? null : new XmlSizeOfEngineLimits(type);
}
});
}
}
return Collections.unmodifiableMap(templates);
}
private Collection<ResourcePool> parseResources(ResourcesType resources) {
Collection<ResourcePool> resourcePools = new ArrayList<ResourcePool>();
for (Element resource : resources.getResource()) {
resourcePools.add(parseResource(resource));
}
return resourcePools;
}
private ResourcePool parseResource(Heap resource) {
ResourceType heapResource = resource.getValue();
return new SizedResourcePoolImpl<SizedResourcePool>(org.ehcache.config.ResourceType.Core.HEAP,
heapResource.getValue().longValue(), parseUnit(heapResource), false);
}
private ResourcePool parseResource(Element element) {
if (!CORE_SCHEMA_NAMESPACE.equals(element.getNamespaceURI())) {
return parseResourceExtension(element);
}
try {
Object resource = unmarshaller.unmarshal(element);
if (resource instanceof Heap) {
ResourceType heapResource = ((Heap) resource).getValue();
return new SizedResourcePoolImpl<SizedResourcePool>(org.ehcache.config.ResourceType.Core.HEAP,
heapResource.getValue().longValue(), parseUnit(heapResource), false);
} else if (resource instanceof Offheap) {
MemoryType offheapResource = ((Offheap) resource).getValue();
return new SizedResourcePoolImpl<SizedResourcePool>(org.ehcache.config.ResourceType.Core.OFFHEAP,
offheapResource.getValue().longValue(), parseMemory(offheapResource), false);
} else if (resource instanceof Disk) {
PersistableMemoryType diskResource = ((Disk) resource).getValue();
return new SizedResourcePoolImpl<SizedResourcePool>(org.ehcache.config.ResourceType.Core.DISK,
diskResource.getValue().longValue(), parseMemory(diskResource), diskResource.isPersistent());
} else {
// Someone updated the core resources without updating *this* code ...
throw new AssertionError("Unrecognized resource: " + element + " / " + resource.getClass().getName());
}
} catch (JAXBException e) {
throw new IllegalArgumentException("Can't find parser for resource: " + element, e);
}
}
private static ResourceUnit parseUnit(ResourceType resourceType) {
if (resourceType.getUnit().value().equalsIgnoreCase("entries")) {
return EntryUnit.ENTRIES;
} else {
return MemoryUnit.valueOf(resourceType.getUnit().value().toUpperCase());
}
}
private static MemoryUnit parseMemory(MemoryType memoryType) {
return MemoryUnit.valueOf(memoryType.getUnit().value().toUpperCase());
}
ServiceCreationConfiguration<?> parseExtension(final Element element) {
URI namespace = URI.create(element.getNamespaceURI());
final CacheManagerServiceConfigurationParser<?> cacheManagerServiceConfigurationParser = xmlParsers.get(namespace);
if(cacheManagerServiceConfigurationParser == null) {
throw new IllegalArgumentException("Can't find parser for namespace: " + namespace);
}
return cacheManagerServiceConfigurationParser.parseServiceCreationConfiguration(element);
}
ServiceConfiguration<?> parseCacheExtension(final Element element) {
URI namespace = URI.create(element.getNamespaceURI());
final CacheServiceConfigurationParser<?> xmlConfigurationParser = cacheXmlParsers.get(namespace);
if(xmlConfigurationParser == null) {
throw new IllegalArgumentException("Can't find parser for namespace: " + namespace);
}
return xmlConfigurationParser.parseServiceConfiguration(element);
}
ResourcePool parseResourceExtension(final Element element) {
URI namespace = URI.create(element.getNamespaceURI());
final CacheResourceConfigurationParser xmlConfigurationParser = resourceXmlParsers.get(namespace);
if (xmlConfigurationParser == null) {
throw new XmlConfigurationException("Can't find parser for namespace: " + namespace);
}
return xmlConfigurationParser.parseResourceConfiguration(element);
}
static class FatalErrorHandler implements ErrorHandler {
@Override
public void warning(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void error(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
throw exception;
}
}
interface CacheTemplate {
String keyType();
String keySerializer();
String keyCopier();
String valueType();
String valueSerializer();
String valueCopier();
String evictionAdvisor();
Expiry expiry();
String loaderWriter();
ListenersConfig listenersConfig();
Iterable<ServiceConfiguration<?>> serviceConfigs();
Collection<ResourcePool> resourcePools();
WriteBehind writeBehind();
DiskStoreSettings diskStoreSettings();
SizeOfEngineLimits heapStoreSettings();
}
interface CacheDefinition extends CacheTemplate {
String id();
}
interface ListenersConfig {
int dispatcherConcurrency();
String threadPool();
Iterable<Listener> listeners();
}
interface Listener {
String className();
EventFiringType eventFiring();
EventOrderingType eventOrdering();
List<EventType> fireOn();
}
interface Expiry {
boolean isUserDef();
boolean isTTI();
boolean isTTL();
String type();
long value();
TimeUnit unit();
}
interface WriteBehind {
int maxQueueSize();
int concurrency();
String threadPool();
Batching batching();
}
interface Batching {
boolean isCoalesced();
int batchSize();
long maxDelay();
TimeUnit maxDelayUnit();
}
interface DiskStoreSettings {
int writerConcurrency();
String threadPool();
int diskSegments();
}
interface SizeOfEngineLimits {
long getMaxObjectGraphSize();
long getMaxObjectSize();
MemoryUnit getUnit();
}
private static class XmlListenersConfig implements ListenersConfig {
final int dispatcherConcurrency;
final String threadPool;
final Iterable<Listener> listeners;
private XmlListenersConfig(final ListenersType type, final ListenersType... others) {
this.dispatcherConcurrency = type.getDispatcherConcurrency().intValue();
String threadPool = type.getDispatcherThreadPool();
Set<Listener> listenerSet = new HashSet<Listener>();
final List<ListenersType.Listener> xmlListeners = type.getListener();
extractListeners(listenerSet, xmlListeners);
for (ListenersType other : others) {
if (threadPool == null && other.getDispatcherThreadPool() != null) {
threadPool = other.getDispatcherThreadPool();
}
extractListeners(listenerSet, other.getListener());
}
this.threadPool = threadPool;
this.listeners = !listenerSet.isEmpty() ? listenerSet : null;
}
private void extractListeners(Set<Listener> listenerSet, List<ListenersType.Listener> xmlListeners) {
if(xmlListeners != null) {
for(final ListenersType.Listener listener : xmlListeners) {
listenerSet.add(new Listener() {
@Override
public String className() {
return listener.getClazz();
}
@Override
public EventFiringType eventFiring() {
return listener.getEventFiringMode();
}
@Override
public EventOrderingType eventOrdering() {
return listener.getEventOrderingMode();
}
@Override
public List<EventType> fireOn() {
return listener.getEventsToFireOn();
}
});
}
}
}
@Override
public int dispatcherConcurrency() {
return dispatcherConcurrency;
}
@Override
public String threadPool() {
return threadPool;
}
@Override
public Iterable<Listener> listeners() {
return listeners;
}
}
private static class XmlExpiry implements Expiry {
final ExpiryType type;
private XmlExpiry(final ExpiryType type) {
this.type = type;
}
@Override
public boolean isUserDef() {
return type != null && type.getClazz() != null;
}
@Override
public boolean isTTI() {
return type != null && type.getTti() != null;
}
@Override
public boolean isTTL() {
return type != null && type.getTtl() != null;
}
@Override
public String type() {
return type.getClazz();
}
@Override
public long value() {
final TimeType time;
if(isTTI()) {
time = type.getTti();
} else {
time = type.getTtl();
}
return time == null ? 0L : time.getValue().longValue();
}
@Override
public TimeUnit unit() {
final TimeType time;
if(isTTI()) {
time = type.getTti();
} else {
time = type.getTtl();
}
if(time != null) {
return XmlModel.convertToJavaTimeUnit(time.getUnit());
}
return null;
}
}
private static class XmlSizeOfEngineLimits implements SizeOfEngineLimits {
private final SizeofType sizeoflimits;
private XmlSizeOfEngineLimits(SizeofType sizeoflimits) {
this.sizeoflimits = sizeoflimits;
}
@Override
public long getMaxObjectGraphSize() {
SizeofType.MaxObjectGraphSize value = sizeoflimits.getMaxObjectGraphSize();
if (value == null) {
return new BigInteger(JaxbHelper.findDefaultValue(sizeoflimits, "maxObjectGraphSize")).longValue();
} else {
return value.getValue().longValue();
}
}
@Override
public long getMaxObjectSize() {
MemoryType value = sizeoflimits.getMaxObjectSize();
if (value == null) {
return new BigInteger(JaxbHelper.findDefaultValue(sizeoflimits, "maxObjectSize")).longValue();
} else {
return value.getValue().longValue();
}
}
@Override
public MemoryUnit getUnit() {
MemoryType value = sizeoflimits.getMaxObjectSize();
if (value == null) {
return MemoryUnit.valueOf(new ObjectFactory().createMemoryType().getUnit().value().toUpperCase());
} else {
return MemoryUnit.valueOf(value.getUnit().value().toUpperCase());
}
}
}
private static class XmlWriteBehind implements WriteBehind {
private final CacheLoaderWriterType.WriteBehind writebehind;
private XmlWriteBehind(CacheLoaderWriterType.WriteBehind writebehind) {
this.writebehind = writebehind;
}
@Override
public int maxQueueSize() {
return this.writebehind.getSize().intValue();
}
@Override
public int concurrency() {
return this.writebehind.getConcurrency().intValue() ;
}
@Override
public String threadPool() {
return this.writebehind.getThreadPool();
}
@Override
public Batching batching() {
CacheLoaderWriterType.WriteBehind.Batching batching = writebehind.getBatching();
if (batching == null) {
return null;
} else {
return new XmlBatching(batching);
}
}
}
private static class XmlBatching implements Batching {
private final CacheLoaderWriterType.WriteBehind.Batching batching;
private XmlBatching(CacheLoaderWriterType.WriteBehind.Batching batching) {
this.batching = batching;
}
@Override
public boolean isCoalesced() {
return this.batching.isCoalesce();
}
@Override
public int batchSize() {
return this.batching.getBatchSize().intValue();
}
@Override
public long maxDelay() {
return this.batching.getMaxWriteDelay().getValue().longValue();
}
@Override
public TimeUnit maxDelayUnit() {
return XmlModel.convertToJavaTimeUnit(this.batching.getMaxWriteDelay().getUnit());
}
}
private static class XmlDiskStoreSettings implements DiskStoreSettings {
private final DiskStoreSettingsType diskStoreSettings;
private XmlDiskStoreSettings(DiskStoreSettingsType diskStoreSettings) {
this.diskStoreSettings = diskStoreSettings;
}
@Override
public int writerConcurrency() {
return this.diskStoreSettings.getWriterConcurrency().intValue();
}
@Override
public String threadPool() {
return this.diskStoreSettings.getThreadPool();
}
@Override
public int diskSegments() {
return this.diskStoreSettings.getDiskSegments().intValue();
}
}
}