All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.tornado.brap.client.MethodInvocationHandler Maven / Gradle / Ivy

package no.tornado.brap.client;

import no.tornado.brap.common.InvocationRequest;
import no.tornado.brap.common.InvocationResponse;
import no.tornado.brap.common.ModificationList;
import no.tornado.brap.exception.RemotingException;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

/**
 * The MethodInvocationHandler is used by the ServiceProxyFactory to provide an implementation
 * of the supplied interface. It intercepts all method-calls and sends them
 * to the server and returns the invocation result.
 * 

* The recommended way to retrieve a service proxy is to call one of the static methods * in the ServiceProxyFactory. */ public class MethodInvocationHandler implements InvocationHandler { private String serviceURI; private Serializable credentials; private static final String REGEXP_PROPERTY_DELIMITER = "\\."; /** * Default constructor to use if you override getServiceURI * and getCredentials to provide "dynamic" service-uri and credentials. */ public MethodInvocationHandler() { } /** * Creates the service proxy on the given URI with the given credentials. *

* Credentials can be changed using the ServiceProxyFactory#setCredentials method. * ServiceURI can be changed using the ServiceProxyFactory#setServiceURI method. * * @param serviceURI The URI to the remote service * @param credentials An object used to authenticate/authorize the request */ public MethodInvocationHandler(String serviceURI, Serializable credentials) { this.serviceURI = serviceURI; this.credentials = credentials; } /** * Creates the service proxy on the given URI. *

* ServiceURI can be changed using the ServiceProxyFactory#setServiceURI method. * * @param serviceURI The URI to the remote service */ public MethodInvocationHandler(String serviceURI) { this(serviceURI, null); } /** * Intercepts the method call towards the proxy and sends the call over HTTP. *

* If an exception is thrown on the server-side, it will be re-thrown to the caller. *

* The return value of the method invocation is returned. * * @return Object the result of the method invocation */ public Object invoke(Object obj, Method method, Object[] args) throws Throwable { InvocationResponse response; try { InvocationRequest request = new InvocationRequest(method, args, getCredentials()); URLConnection conn = new URL(getServiceURI()).openConnection(); conn.setDoOutput(true); ObjectOutputStream out = new ObjectOutputStream(conn.getOutputStream()); out.writeObject(request); ObjectInputStream in = new ObjectInputStream(conn.getInputStream()); response = (InvocationResponse) in.readObject(); applyModifications(args, response.getModifications()); } catch (IOException e) { throw new RemotingException(e); } if (response.getException() != null) throw response.getException(); return response.getResult(); } private void applyModifications(Object[] args, ModificationList[] modifications) { if (modifications != null) { for (int i = 0; i < modifications.length; i++) { ModificationList mods = modifications[i]; if (mods != null) { Iterator> it = mods.getModifiedProperties().entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = it.next(); try { setModifiedValue(entry.getKey(), entry.getValue(), args[i]); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } private void setModifiedValue(String key, Object value, Object object) throws NoSuchFieldException, IllegalAccessException { String[] propertyGraph = key.split(REGEXP_PROPERTY_DELIMITER); int i = 0; for (; i < propertyGraph.length - 1; i++) object = getValue(object, object.getClass().getDeclaredField(propertyGraph[i])); setValue(object, object.getClass().getDeclaredField(propertyGraph[i]), value); } private void setValue(Object object, Field field, Object value) throws IllegalAccessException { boolean accessible = field.isAccessible(); if (!accessible) field.setAccessible(true); field.set(object, value); if (!accessible) field.setAccessible(false); } private Object getValue(Object object, Field field) throws IllegalAccessException { boolean accessible = field.isAccessible(); if (!accessible) field.setAccessible(true); Object value = field.get(object); if (!accessible) field.setAccessible(false); return value; } /** * Getter for the ServiceURI. Override if you need a more dynamic serviceURI * than just setting the value. * * @return The serviceURI for subsequent method invocations. * @see no.tornado.brap.client.ServiceProxyFactory#setServiceURI(Object, String) */ public String getServiceURI() { return serviceURI; } public void setServiceURI(String serviceURI) { this.serviceURI = serviceURI; } /** * Getter for the credentials. Override if you need more dynamic credentials * than just setting the values. * * @return The credentials to use for subsequent method invocations. * @see no.tornado.brap.client.ServiceProxyFactory#setCredentials(Object, java.io.Serializable) */ public Serializable getCredentials() { return credentials; } public void setCredentials(Serializable credentials) { this.credentials = credentials; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy