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

org.gridkit.vicluster.CloudContext Maven / Gradle / Ivy

There is a newer version: 1.0.0-beta
Show newest version
package org.gridkit.vicluster;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.Callable;

public interface CloudContext {

	public  T lookup(ServiceKey key);

	public  T lookup(ServiceKey key, Callable provider);

	public  T lookup(ServiceKey key, ServiceProvider provider);
	
	public void addFinalizer(Runnable finalizer);
	
	public static interface ServiceProvider {
		
		public T getService(CloudContext context);
		
	}
	
	public static class ServiceKey {
		
		private Class type;
		private java.util.Map props = new LinkedHashMap();

		public ServiceKey(Class type) {
			this(type, Collections.emptyMap());
		}

		public ServiceKey(Class type, java.util.Map keyProps) {
			this.type = type;
			props.putAll(keyProps);
		}
		
		public java.util.Map asComparableMap() {
			return new TreeMap (props);
		}
		
		public Class getType() {
			return type;
		}
		
		public ServiceKey with(String key, String value) {
			ServiceKey that = new ServiceKey(type, props);
			that.props.put(key, value);
			return that;
		}
		
		@Override
		public int hashCode() {
			return asComparableMap().hashCode();
		}

		@Override
		public boolean equals(Object obj) {
			if (obj instanceof ServiceKey) {
				return asComparableMap().equals(((ServiceKey) obj).asComparableMap());
			}
			else {
				return false;
			}
		}
		
		public List> getClassHierary() {
			List> h = new ArrayList>();
			collectHierarchy(h, type);
			return h;
		}

		private void collectHierarchy(List> h, Class t) {
			if (!h.contains(t)) {
				h.add(t);
			}
			if (t.getInterfaces() != null) {
				for(Class i: t.getInterfaces()) {
					collectHierarchy(h, i);
				}
			}
			if (t != Object.class && t.getSuperclass() != null) {
				collectHierarchy(h, t.getSuperclass());
			}			
		}

		public String toString() {
			return type.getSimpleName() + props.toString();
		}
	}
	
	public static class Helper {
		
		public static  ServiceKey key(Class type) {
			return new ServiceKey(type);
		}

		public static  ServiceKey key(Class type, String propName, String value) {
			return new ServiceKey(type, Collections.singletonMap(propName, value));
		}
				
		
		public static  ServiceProvider reflectionProvider(final Class type, final String finalizerMethod) {
			try {
				if (finalizerMethod != null) {
					// verify finalizer
					type.getMethod(finalizerMethod);
				}
				Constructor c = type.getConstructor();
				if (!Modifier.isPublic(c.getModifiers())) {
					throw new RuntimeException("Class " + type.getName() + " does not have public no argument constructor");
				}
			} catch (SecurityException e) {
				throw new RuntimeException(e);
			} catch (NoSuchMethodException e) {
				throw new RuntimeException(e);
			}
			
			ServiceProvider provider = new ServiceProvider() {

				@Override
				public T getService(CloudContext context) {
					try {
						T service = (T)type.newInstance();
						if (finalizerMethod != null) {
							context.addFinalizer(reflectionFinalizer(service, finalizerMethod));
						}
						return service;
					} catch (InstantiationException e) {
						throw new RuntimeException(e);
					} catch (IllegalAccessException e) {
						throw new RuntimeException(e);
					}
				}
			};
			
			
			return provider;
		}

		public static Runnable closeableFinalizer(final Closeable obj) {
			return new Runnable() {
				@Override
				public void run() {
					try {
						obj.close();
					} catch (IOException e) {
						// ignore
					}
				}
			};
		}

		public static Runnable reflectionFinalizer(final Object obj, String finalizerMethod) {
			try {
				final Method m = obj.getClass().getMethod(finalizerMethod);
				m.setAccessible(true);
				return new Runnable() {
					@Override
					public void run() {
						try {
							m.invoke(obj);
						} catch (IllegalArgumentException e) {
							throw new RuntimeException(e);
						} catch (IllegalAccessException e) {
							throw new RuntimeException(e);
						} catch (InvocationTargetException e) {
							if (e.getCause() instanceof RuntimeException) {
								throw (RuntimeException)e.getCause();
							}
							else if (e.getCause() instanceof Error) {
								throw (Error)e.getCause();
							}
							else {
								throw new RuntimeException(e.getCause());
							}
						}
					}

					@Override
					public String toString() {
						return "FIN[" + m.getName() + "@" + obj.toString() + "]";
					}
				};
			} catch (SecurityException e) {
				throw new RuntimeException(e);
			} catch (NoSuchMethodException e) {
				throw new RuntimeException(e);
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy