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

com.github.gkutiel.flip.utils.Utils Maven / Gradle / Ivy

There is a newer version: 10-RELEASE
Show newest version
package com.github.gkutiel.flip.utils;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.io.IOUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import com.github.gkutiel.flip.utils.Utils.Reflection.AbstractObjectVisitor;
import com.thoughtworks.paranamer.BytecodeReadingParanamer;
import com.thoughtworks.paranamer.Paranamer;

/**
 * Utility class for the flip framework
 * 
 * @author gilad
 */
public enum Utils {
	;
	public static enum Collections {
		;
		public interface Filter {
			boolean accept(T t);
		}

		public interface Transformer {
			T2 transform(T1 t1);
		}

		/**
		 * @param list
		 * @param filter
		 * @return a new list containing only the elements accepted by the filter
		 */
		public static  List filter(final List list, final Filter filter) {
			final List newList = new ArrayList<>();

			for (final T t : list)
				if (filter.accept(t)) newList.add(t);

			return newList;
		}

		public static  List transform(final List list, final Transformer transformer) {
			final List newList = new ArrayList<>();

			for (final T1 t1 : list)
				newList.add(transformer.transform(t1));

			return newList;
		}

		public static  Map transformValues(final Map map, final Transformer transformer) {
			final Map newMap = new HashMap<>();

			for (final Entry e : map.entrySet())
				newMap.put(e.getKey(), transformer.transform(e.getValue()));

			return newMap;
		}
	}

	public static enum Cryptography {
		;
		private static final KeyPair KEY_PAIR;
		private static final HexBinaryAdapter ADAPTER = new HexBinaryAdapter();
		private static final String SIG_ALG = "SHA1withDSA";

		static {
			try {
				KEY_PAIR = KeyPairGenerator.getInstance("DSA").generateKeyPair();
			} catch (final NoSuchAlgorithmException e) {
				throw new RuntimeException(e);
			}
		}

		public static String sign(final byte[] data) {
			try {
				final Signature sig = Signature.getInstance(SIG_ALG);
				sig.initSign(KEY_PAIR.getPrivate());
				sig.update(data);
				return ADAPTER.marshal(sig.sign());
			} catch (final Exception e) {
				throw new RuntimeException(e);
			}
		}

		public static String sign(final String data) {
			return sign(data.getBytes());
		}

		public static boolean verify(final byte[] data, final String sign) {
			try {
				final Signature sig = Signature.getInstance(SIG_ALG);
				sig.initVerify(KEY_PAIR.getPublic());
				sig.update(data);
				return sig.verify(ADAPTER.unmarshal(sign));
			} catch (final Exception e) {
				return false;
			}
		}

		public static boolean verify(final String data, final String sign) {
			return verify(data.getBytes(), sign);
		}
	}

	public static enum Json {
		;
		private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

		public static  T fromString(final String json, final Class type) throws IOException {
			return OBJECT_MAPPER.readValue(json, type);
		}

		public static String toString(final Object o) {
			if (o == null) return "null";
			final StringBuilder json = new StringBuilder();
			Reflection.accept(o, new AbstractObjectVisitor() {
				private String escape(final String s) {
					return s.replaceAll("\\\"", "\\\\\"");
				}

				@Override
				public void visitArray(final int[] is) {
					if (is.length == 0) {
						json.append("[]");
						return;
					}
					json.append("[" + is[0]);
					for (int i = 1; i < is.length; i++) {
						json.append(",");
						json.append(is[i]);
					}
					json.append("]");
				}

				@Override
				public void visitArray(final Object[] a) {
					this.visitList(java.util.Arrays.asList(a));
				}

				@Override
				public void visitBoolean(final Boolean b) {
					json.append(b);
				}

				@Override
				public void visitDefault(final Object o) {
					try {
						if (o == null) {
							json.append("null");
							return;
						}
						final Class clazz = o.getClass();
						final Field[] fields = clazz.getDeclaredFields();
						if (fields == null) {
							json.append("{}");
							return;
						}
						AccessibleObject.setAccessible(fields, true);
						final Map map = new HashMap<>();
						for (final Field field : fields)
							map.put(field.getName(), field.get(o));
						this.visitMap(map);
					} catch (final Exception e) {
						throw new RuntimeException(e);
					}
				}

				private void visitIterable(final Iterable s) {
					final Iterator it = s.iterator();
					if (!it.hasNext()) {
						json.append("[]");
						return;
					}
					json.append("[");
					Reflection.accept(it.next(), this);
					while (it.hasNext()) {
						json.append(",");
						Reflection.accept(it.next(), this);
					}
					json.append("]");
				}

				@Override
				public void visitList(final List l) {
					this.visitIterable(l);
				}

				@Override
				public void visitMap(final Map m) {
					if (m.size() == 0) {
						json.append("{}");
						return;
					}
					json.append("{");
					final Iterator it = m.entrySet().iterator();
					Entry e = (Entry) it.next();
					json.append("\"");
					json.append(e.getKey());
					json.append("\"");
					json.append(":");
					Reflection.accept(e.getValue(), this);
					while (it.hasNext()) {
						json.append(",");
						e = (Entry) it.next();
						json.append("\"");
						json.append(e.getKey());
						json.append("\"");
						json.append(":");
						Reflection.accept(e.getValue(), this);
					}
					json.append("}");
				}

				@Override
				public void visitNumber(final Number n) {
					json.append(n.toString());
				}

				@Override
				public void visitSet(final Set s) {
					this.visitIterable(s);
				}

				@Override
				public void visitString(final String s) {
					json.append("\"");
					json.append(this.escape(s));
					json.append("\"");
				}

			});
			return json.toString();
		}
	}

	public static enum Reflection {
		;
		public static abstract class AbstractObjectVisitor implements ObjectVisitor {
			@Override
			public void visitArray(final double[] o) {
				this.visitDefault(o);
			}

			@Override
			public void visitArray(final int[] is) {
				this.visitDefault(is);
			}

			@Override
			public void visitArray(final long[] o) {
				this.visitDefault(o);
			}

			@Override
			public void visitArray(final Object[] a) {
				this.visitDefault(a);
			}

			@Override
			public void visitBoolean(final Boolean b) {
				this.visitDefault(b);
			}

			@Override
			public void visitClass(final Class c) {
				this.visitDefault(c);
			}

			public abstract void visitDefault(Object o);

			@Override
			public void visitList(final List l) {
				this.visitDefault(l);
			}

			@Override
			public void visitMap(final Map m) {
				this.visitDefault(m);
			}

			@Override
			public void visitNull() {
				this.visitDefault(null);
			}

			@Override
			public void visitNumber(final Number n) {
				this.visitDefault(n);
			}

			@Override
			public void visitObject(final Object o) {
				this.visitDefault(o);
			}

			@Override
			public void visitSet(final Set s) {
				this.visitDefault(s);
			}

			@Override
			public void visitString(final String s) {
				this.visitDefault(s);
			}

		}

		public static interface ObjectVisitor {

			void visitArray(double[] o);

			void visitArray(int[] o);

			void visitArray(long[] o);

			void visitArray(Object[] a);

			void visitBoolean(Boolean b);

			void visitClass(Class c);

			void visitList(List l);

			void visitMap(Map m);

			void visitNull();

			void visitNumber(Number n);

			void visitObject(Object o);

			void visitSet(Set s);

			void visitString(String s);
		}

		private static HashSet> WRAPPERS = new HashSet<>();

		static {
			WRAPPERS.add(Boolean.class);
			WRAPPERS.add(Byte.class);
			WRAPPERS.add(Character.class);
			WRAPPERS.add(Short.class);
			WRAPPERS.add(Float.class);
			WRAPPERS.add(Integer.class);
			WRAPPERS.add(Long.class);
			WRAPPERS.add(Double.class);
			WRAPPERS.add(String.class);
		}

		private static final Paranamer PARANAMER = new BytecodeReadingParanamer();

		public static void accept(final Object o, final ObjectVisitor visitor) {
			if (o == null) visitor.visitNull();
			else if (o instanceof Boolean) visitor.visitBoolean((Boolean) o);
			else if (o instanceof Number) visitor.visitNumber((Number) o);
			else if (o instanceof String) visitor.visitString((String) o);
			else if (o instanceof Class) visitor.visitClass((Class) o);
			else if (o instanceof Map) visitor.visitMap((Map) o);
			else if (o instanceof List) visitor.visitList((List) o);
			else if (o instanceof Set) visitor.visitSet((Set) o);
			else if (o.getClass().isArray()) {
				if (o instanceof Object[]) visitor.visitArray((Object[]) o);
				else if (o instanceof int[]) visitor.visitArray((int[]) o);
				else if (o instanceof long[]) visitor.visitArray((long[]) o);
				else if (o instanceof double[]) visitor.visitArray((double[]) o);
			} else visitor.visitObject(o);
		}

		public static Method findFirstMethod(final Class clazz, final String methodName) {
			final Method[] methods = clazz.getDeclaredMethods();
			AccessibleObject.setAccessible(methods, true);
			for (final Method method : methods)
				if (method.getName().equals(methodName)) return method;
			return null;
		}

		public static Map> getFormalParams(final Method method) {
			final Map> params = new HashMap<>();

			final Class[] paramTypes = method.getParameterTypes();
			final String[] paramNames = PARANAMER.lookupParameterNames(method);
			for (int i = 0; i < paramNames.length; i++)
				params.put(paramNames[i], paramTypes[i]);

			return params;
		}

		public static Object invoke(final Method method, final Object instance, final Map params) throws IllegalAccessException,
				IllegalArgumentException, InvocationTargetException {
			final String[] paramNames = PARANAMER.lookupParameterNames(method);
			final Object[] actualParams = new Object[paramNames.length];
			for (int i = 0; i < actualParams.length; i++)
				actualParams[i] = params.get(paramNames[i]);
			return method.invoke(instance, actualParams);
		}

		public static boolean isWrapper(final Object o) {
			return WRAPPERS.contains(o.getClass());
		}

	}

	public enum Resource {
		;
		public static String load(final String fileName) {
			try {
				return IOUtils.toString(ClassLoader.getSystemClassLoader().getResourceAsStream(fileName));
			} catch (final IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

	public static enum Strings {
		;
		public static String concat(final String delimeter, final String... strings) {
			if (strings == null || strings.length == 0) return EMPTY_STRING;
			final StringBuilder builder = new StringBuilder();
			builder.append(strings[0]);
			for (int i = 1; i < strings.length; i++) {
				builder.append(delimeter);
				builder.append(strings[i]);
			}
			return builder.toString();
		}

		public static String emptyIfNull(final String str) {
			return str == null ? EMPTY_STRING : str;
		}

		public static boolean emptyOrNull(final String str) {
			return str == null || str.length() == 0;
		}
	}

	public static enum Url {
		;
		public static String urlEncode(final Map args) {
			try {
				if (args == null || args.size() == 0) return EMPTY_STRING;
				final StringBuilder builder = new StringBuilder();
				final Iterator it = args.entrySet().iterator();
				@SuppressWarnings("unchecked")
				final Entry arg = (Entry) it.next();
				builder.append(URLEncoder.encode(arg.getKey(), UTF_8));
				builder.append("=");
				builder.append(URLEncoder.encode(arg.getValue().toString(), UTF_8));
				while (it.hasNext()) {
					builder.append("&");
					builder.append(URLEncoder.encode(arg.getKey(), UTF_8));
					builder.append("=");
					builder.append(URLEncoder.encode(arg.getValue().toString(), UTF_8));
				}
				return builder.toString();
			} catch (final UnsupportedEncodingException e) {
				throw new RuntimeException(e);
			}
		}

	}

	public static enum Xml {
		;

		private static String getName(final Object val) {
			if (val == null) return "null";
			return val.getClass().getSimpleName().replace("[]", "s");
		}

		public static String toString(final Document doc) throws TransformerConfigurationException, TransformerException, TransformerFactoryConfigurationError {
			final StringWriter stringWriter = new StringWriter();
			TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc), new StreamResult(stringWriter));
			return stringWriter.toString();
		}

		private static void toXml(final Document doc, final Node parent, final String name, final Object val) {
			if (val == null) return;
			final Node p = parent;
			final Element childElement = doc.createElement(name);
			p.appendChild(childElement);
			Reflection.accept(val, new Reflection.AbstractObjectVisitor() {

				@Override
				public void visitArray(final double[] ds) {
					for (final double d : ds)
						toXml(doc, childElement, "double", d);
				}

				@Override
				public void visitArray(final int[] is) {
					for (final int d : is)
						toXml(doc, childElement, "int", d);
				}

				@Override
				public void visitArray(final long[] ls) {
					for (final long l : ls)
						toXml(doc, childElement, "long", l);
				}

				@Override
				public void visitArray(final Object[] a) {
					for (final Object val : a)
						toXml(doc, childElement, val.getClass().getSimpleName(), val);
				}

				@Override
				public void visitClass(final Class c) {
					childElement.setTextContent(c.getName());
				}

				@Override
				public void visitDefault(final Object o) {
					if (Reflection.isWrapper(val)) childElement.setTextContent(String.valueOf(val));
					else {
						final Class clazz = val.getClass();
						final Field[] fields = clazz.getDeclaredFields();
						AccessibleObject.setAccessible(fields, true);
						for (final Field field : fields)
							try {
								toXml(doc, childElement, field.getName(), field.get(val));
							} catch (IllegalArgumentException | IllegalAccessException e) {
								throw new RuntimeException(e);
							}
					}
				}

				@Override
				public void visitList(final List l) {
					for (final Object listValue : l)
						toXml(doc, childElement, listValue.getClass().getSimpleName(), listValue);
				}

				@Override
				public void visitMap(final Map m) {
					for (final Entry en : m.entrySet()) {
						final Element entry = doc.createElement("entry");
						childElement.appendChild(entry);
						toXml(doc, entry, "key", en.getKey());
						toXml(doc, entry, "val", en.getValue());
					}
				}
			});
		}

		public static Document toXml(final Object val) throws ParserConfigurationException, IllegalArgumentException {
			final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
			final Element flip = doc.createElement("flip");
			doc.appendChild(flip);
			toXml(doc, flip, getName(val), val);
			return doc;
		}
	}

	private static final String EMPTY_STRING = "";
	private static final String UTF_8 = "UTF-8";
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy