/*
* Copyright 2011, 2012 Odysseus Software GmbH
*
* 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 de.odysseus.staxon.json.jaxrs.jaxb;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Providers;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
public class JsonXMLContextStore {
static class CacheKey {
private final int hashCode;
private final Class<?>[] classes;
CacheKey(Class<?>... classes) {
int classesHashCode = 0;
for (Class<?> clazz : classes) {
classesHashCode ^= clazz.hashCode();
}
this.hashCode = classesHashCode;
this.classes = classes;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass() || hashCode() != obj.hashCode()) {
return false;
}
CacheKey other = (CacheKey) obj;
if (!Arrays.equals(classes, other.classes)) {
return false;
}
return true;
}
@Override
public int hashCode() {
return hashCode;
}
}
private final ConcurrentHashMap<CacheKey, JAXBContext> cache = new ConcurrentHashMap<CacheKey, JAXBContext>();
private final Providers providers;
public JsonXMLContextStore(Providers providers) {
this.providers = providers;
}
protected JAXBContext createContext(Class<?>... types) throws JAXBException {
return JAXBContext.newInstance(types);
}
public JAXBContext getContext(Class<?> type, MediaType mediaType) throws JAXBException {
CacheKey key = new CacheKey(type);
JAXBContext result = cache.get(key);
if (result != null) {
return result;
}
if (providers != null) {
ContextResolver<JAXBContext> resolver = providers.getContextResolver(JAXBContext.class, mediaType);
if (resolver != null) {
result = resolver.getContext(type);
if (result != null) {
return cache.putIfAbsent(key, result) == null ? result : cache.get(key);
}
}
}
result = createContext(type);
if (result != null) {
return cache.putIfAbsent(key, result) == null ? result : cache.get(key);
}
return null;
}
}