/*
* Copyright (c) 2012 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.api.service.impl.resource;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.*;
import com.emc.storageos.svcs.errorhandling.resources.APIException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* JAXB context provider with validation bits
*/
@Provider
public class ContextProvider implements ContextResolver<JAXBContext> {
private ConcurrentMap<Class, ValidatingContext> _contextMap =
new ConcurrentHashMap<Class, ValidatingContext>();
/**
* Wraps default JAXB provider with a couple of validation bits
*/
@SuppressWarnings("deprecation")
public static class ValidatingContext extends JAXBContext {
private JAXBContext _context;
/**
* Throws error on any unexpected element, etc.
*/
private static final ValidationEventHandler _eventHandler = new ValidationEventHandler() {
@Override
public boolean handleEvent(ValidationEvent event) {
throw APIException.badRequests.invalidInput(event.getLocator().getLineNumber(), event.getLocator().getColumnNumber());
}
};
/**
* Throws error on any missing parameters
*/
private static final Unmarshaller.Listener _unmarshallListener = new Unmarshaller.Listener() {
@Override
public void afterUnmarshal(Object target, Object parent) {
InputValidator.getInstance().validate(target);
}
};
public ValidatingContext(JAXBContext context) {
_context = context;
}
@Override
public Unmarshaller createUnmarshaller() throws JAXBException {
Unmarshaller unmarshaller = _context.createUnmarshaller();
unmarshaller.setEventHandler(_eventHandler);
unmarshaller.setListener(_unmarshallListener);
return unmarshaller;
}
@Override
public Marshaller createMarshaller() throws JAXBException {
return _context.createMarshaller();
}
@Override
public Validator createValidator() throws JAXBException {
return _context.createValidator();
}
}
@Override
public JAXBContext getContext(Class<?> clazz) {
try {
ValidatingContext ctx = _contextMap.get(clazz);
if (ctx != null) {
return ctx;
}
JAXBContext context = JAXBContext.newInstance(clazz);
ctx = new ValidatingContext(context);
_contextMap.putIfAbsent(clazz, ctx);
return ctx;
} catch (JAXBException e) {
throw APIException.internalServerErrors.jaxbContextError(e.getMessage(), e);
}
}
}