package io.hummer.prefetch.ws;
/**
* Version: MPL 1.1/EUPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Copyright The PEPPOL project (http://www.peppol.eu)
*
* Alternatively, the contents of this file may be used under the
* terms of the EUPL, Version 1.1 or - as soon they will be approved
* by the European Commission - subsequent versions of the EUPL
* (the "Licence"); You may not use this work except in compliance
* with the Licence.
* You may obtain a copy of the Licence at:
* http://www.osor.eu/eupl/european-union-public-licence-eupl-v.1.1
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*
* If you wish to allow use of your version of this file only
* under the terms of the EUPL License and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the EUPL License. If you do not delete
* the provisions above, a recipient may use your version of this file
* under either the MPL or the EUPL License.
*/
import java.lang.reflect.Field;
import java.util.List;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
import org.w3c.dom.Element;
/**
* As the default WS-Addressing binding since JAXB 2.1 uses the
* {@link W3CEndpointReference} class, we must also use this class, otherwise
* JAXB would complain, that there are 2 contexts for the same namespace+element
* combination.<br>
* The issue with {@link W3CEndpointReference} is that it can easily be created
* using the {@link W3CEndpointReferenceBuilder} class, but it's not possible to
* extract information from it (get....). This class offers a <b>*HACK*</b>
* workaround by using reflection (incl. setAccessible) to access private fields
* of {@link W3CEndpointReference}. This was only tested on Sun JDKs, so use at
* your own risk!!!
*
* @author PEPPOL.AT, BRZ, Philip Helger
*/
public final class W3CEndpointReferenceUtils {
private static Field s_aFieldAddress;
private static Field s_aFieldReferenceParameters;
private static Field s_aFieldAddressURI;
private static Field s_aFieldElementsElements;
static {
// Resolve inner classes
final String sAddress = W3CEndpointReference.class.getName()
+ "$Address";
final String sElements = W3CEndpointReference.class.getName()
+ "$Elements";
Class<?> aClassAddress = null;
Class<?> aClassElements = null;
// for all inner classes
for (final Class<?> aClass : W3CEndpointReference.class
.getDeclaredClasses()) {
final String sClassName = aClass.getName();
if (sClassName.equals(sAddress))
aClassAddress = aClass;
else if (sClassName.equals(sElements))
aClassElements = aClass;
}
if (aClassAddress == null)
throw new RuntimeException("Failed to resolve class " + sAddress);
if (aClassElements == null)
throw new RuntimeException("Failed to resolve class " + sElements);
try {
// Resolve required fields and make them accessible
s_aFieldAddress = W3CEndpointReference.class
.getDeclaredField("address");
// TODO use PrivilegedAction in phloc-commons >= 3.0.1
s_aFieldAddress.setAccessible(true);
s_aFieldReferenceParameters = W3CEndpointReference.class
.getDeclaredField("referenceParameters");
s_aFieldReferenceParameters.setAccessible(true);
s_aFieldAddressURI = aClassAddress.getDeclaredField("uri");
s_aFieldAddressURI.setAccessible(true);
s_aFieldElementsElements = aClassElements
.getDeclaredField("elements");
s_aFieldElementsElements.setAccessible(true);
} catch (final Throwable t) {
throw new RuntimeException(
"Failed to init W3CEndpointReference Fields for reflection");
}
}
private W3CEndpointReferenceUtils() {
}
/**
* Create a new endpoint reference for the given address without reference
* parameters.
*
* @param sAddress
* The address to use. May not be <code>null</code>.
* @return The non-<code>null</code> endpoint reference for the given
* address
*/
public static W3CEndpointReference createEndpointReference(
final String sAddress) {
return new W3CEndpointReferenceBuilder().address(sAddress).build();
}
/**
* Create a new endpoint reference for the given address, using the
* specified reference parameters.
*
* @param sAddress
* The address to use. May not be <code>null</code>.
* @param aReferenceParameters
* The non-<code>null</code> list of reference parameters. May
* not be <code>null</code>.
* @return The non-<code>null</code> endpoint reference for the given
* address
*/
public static W3CEndpointReference createEndpointReference(
final String sAddress, final List<Element> aReferenceParameters) {
W3CEndpointReferenceBuilder aBuilder = new W3CEndpointReferenceBuilder()
.address(sAddress);
for (final Element aReferenceParameter : aReferenceParameters) {
aBuilder = aBuilder.referenceParameter(aReferenceParameter);
}
return aBuilder.build();
}
/**
* Get the address contained in the passed endpoint reference.
*
* @param aEndpointReference
* The endpoint reference to retrieve the address from. May not
* be <code>null</code>.
* @return The contained address.
*/
public static String getAddress(
final W3CEndpointReference aEndpointReference) {
try {
// Get the "address" value of the endpoint reference
final Object aAddress = s_aFieldAddress.get(aEndpointReference);
if (aAddress == null)
return null;
// Get the "uri" out of the "address" field
return (String) s_aFieldAddressURI.get(aAddress);
} catch (final Throwable t) {
throw new IllegalStateException(t);
}
}
/**
* Get a list of all reference parameters contained in the passed endpoint
* reference.
*
* @param aEndpointReference
* The endpoint reference to retrieve the reference parameters.
* May not be <code>null</code>.
* @return A mutable element list
*/
@SuppressWarnings("unchecked")
public static List<Element> getReferenceParameters(
final W3CEndpointReference aEndpointReference) {
try {
// Get the "referenceParameters" value of the endpoint reference
final Object aReferenceParameters = s_aFieldReferenceParameters
.get(aEndpointReference);
if (aReferenceParameters == null)
return null;
// Get the "elements" out of the "referenceParameters" field
return (List<Element>) s_aFieldElementsElements
.get(aReferenceParameters);
} catch (final Throwable t) {
throw new IllegalStateException(t);
}
}
/**
* Get the reference parameter at the given index
*
* @param aEndpointReference
* The object to retrieve the reference parameter from. May not
* be <code>null</code>.
* @param nIndex
* The index to retrieve. Should not be negative.
* @return <code>null</code> if the index is invalid
*/
public static Element getReferenceParameter(
final W3CEndpointReference aEndpointReference, final int nIndex) {
// Get all reference parameters
final List<Element> aReferenceParameters = getReferenceParameters(aEndpointReference);
// And extract the one at the desired index.
return aReferenceParameters.get(nIndex);
}
}