/******************************************************************************* * Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * - rbarkhouse - 24 February 2012 - 2.3.3 - Initial implementation ******************************************************************************/ package org.eclipse.persistence.internal.jaxb; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.Callable; import javax.xml.bind.ValidationEventHandler; import org.eclipse.persistence.exceptions.XMLMarshalException; import org.eclipse.persistence.internal.core.helper.CoreClassConstants; import org.eclipse.persistence.internal.security.PrivilegedAccessHelper; import org.eclipse.persistence.jaxb.IDResolver; import org.xml.sax.SAXException; /** * INTERNAL: * <p> * This class provides an implementation of IDResolver that wraps * an IDResolver from the Sun JAXB Implementation. * </p> */ public class IDResolverWrapper extends IDResolver { private final static String BIND_METHOD_NAME = "bind"; private final static String END_DOCUMENT_METHOD_NAME = "endDocument"; private final static String RESOLVE_METHOD_NAME = "resolve"; private final static String START_DOCUMENT_METHOD_NAME = "startDocument"; private final static Class[] BIND_PARAMS = new Class[] { CoreClassConstants.STRING, CoreClassConstants.OBJECT }; private final static Class[] RESOLVE_PARAMS = new Class[] { CoreClassConstants.STRING, CoreClassConstants.CLASS }; private final static Class[] START_DOCUMENT_PARAMS = new Class[] { ValidationEventHandler.class }; private Object resolver; private Method bindMethod, endDocumentMethod, resolveMethod, startDocumentMethod; public IDResolverWrapper(Object sunResolver) { this.resolver = sunResolver; Class resolverClass = sunResolver.getClass(); try { this.bindMethod = PrivilegedAccessHelper.getMethod(resolverClass, BIND_METHOD_NAME, BIND_PARAMS, false); } catch (Exception ex) { throw XMLMarshalException.errorProcessingIDResolver(BIND_METHOD_NAME, sunResolver, ex); } try { this.endDocumentMethod = PrivilegedAccessHelper.getMethod(resolverClass, END_DOCUMENT_METHOD_NAME, new Class[] {}, false); } catch (Exception ex) { throw XMLMarshalException.errorProcessingIDResolver(END_DOCUMENT_METHOD_NAME, sunResolver, ex); } try { this.resolveMethod = PrivilegedAccessHelper.getMethod(resolverClass, RESOLVE_METHOD_NAME, RESOLVE_PARAMS, false); } catch (Exception ex) { throw XMLMarshalException.errorProcessingIDResolver(RESOLVE_METHOD_NAME, sunResolver, ex); } try { this.startDocumentMethod = PrivilegedAccessHelper.getMethod(resolverClass, START_DOCUMENT_METHOD_NAME, START_DOCUMENT_PARAMS, false); } catch (Exception ex) { throw XMLMarshalException.errorProcessingIDResolver(START_DOCUMENT_METHOD_NAME, sunResolver, ex); } } @Override public void bind(Object id, Object obj) throws SAXException { try { Object[] params = new Object[] { id.toString(), obj }; PrivilegedAccessHelper.invokeMethod(this.bindMethod, this.resolver, params); } catch (Exception ex) { throw XMLMarshalException.errorInvokingIDResolver(BIND_METHOD_NAME, this.resolver, ex); } } @Override public void endDocument() throws SAXException { try { PrivilegedAccessHelper.invokeMethod(this.endDocumentMethod, this.resolver, new Object[] {}); } catch (Exception ex) { throw XMLMarshalException.errorInvokingIDResolver(END_DOCUMENT_METHOD_NAME, this.resolver, ex); } } @Override public void startDocument(ValidationEventHandler eventHandler) throws SAXException { try { Object[] params = new Object[] { eventHandler }; PrivilegedAccessHelper.invokeMethod(this.startDocumentMethod, this.resolver, params); } catch (Exception ex) { throw XMLMarshalException.errorInvokingIDResolver(START_DOCUMENT_METHOD_NAME, this.resolver, ex); } } @Override public Callable<?> resolve(Object id, Class targetType) throws SAXException { try { Object[] params = new Object[] { id.toString(), targetType }; return (Callable<?>) PrivilegedAccessHelper.invokeMethod(this.resolveMethod, this.resolver, params); } catch (Exception ex) { throw XMLMarshalException.errorInvokingIDResolver(RESOLVE_METHOD_NAME, this.resolver, ex); } } @Override public Callable<?> resolve(Map<String, Object> id, Class type) throws SAXException { // If the user is still using a Sun IDResolver, then they must only have one XML ID, // as only EclipseLink supports multiple IDs through XmlKey. So if this method is called, // throw an exception informing the user. throw XMLMarshalException.wrappedIDResolverWithMultiID(id.toString(), this.resolver); } @Override public void bind(Map<String, Object> id, Object obj) throws SAXException { // If the user is still using a Sun IDResolver, then they must only have one XML ID, // as only EclipseLink supports multiple IDs through XmlKey. So if this method is called, // throw an exception informing the user. throw XMLMarshalException.wrappedIDResolverWithMultiID(id.toString(), this.resolver); } public Object getResolver() { return this.resolver; } }