package org.javers.core.graph; import org.javers.core.metamodel.object.Cdo; import org.javers.core.metamodel.type.TypeMapper; import java.lang.reflect.Array; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; /** * @author bartosz walacik */ public class LiveGraphFactory { private final TypeMapper typeMapper; private final LiveCdoFactory liveCdoFactory; private final CollectionsCdoFactory collectionsCdoFactory; public LiveGraphFactory(TypeMapper typeMapper, LiveCdoFactory liveCdoFactory, CollectionsCdoFactory collectionsCdoFactory) { this.typeMapper = typeMapper; this.liveCdoFactory = liveCdoFactory; this.collectionsCdoFactory = collectionsCdoFactory; } public LiveGraph createLiveGraph(Collection handle, Class clazz) { CollectionWrapper wrappedCollection = (CollectionWrapper) wrapTopLevelContainer(handle); return new CollectionsGraphBuilder(new ObjectGraphBuilder(typeMapper, liveCdoFactory), collectionsCdoFactory) .buildGraph(wrappedCollection, clazz); } /** * delegates to {@link ObjectGraphBuilder#buildGraph(Object)} */ public LiveGraph createLiveGraph(Object handle) { Object wrappedHandle = wrapTopLevelContainer(handle); return new ObjectGraphBuilder(typeMapper, liveCdoFactory).buildGraph(wrappedHandle); } public Cdo createCdo(Object cdo){ return liveCdoFactory.create(cdo, null); } private Object wrapTopLevelContainer(Object handle){ if (handle instanceof Map){ return new MapWrapper((Map)handle); } if (handle instanceof List){ return new ListWrapper((List)handle); } if (handle instanceof Set){ return new SetWrapper((Set)handle); } if (handle.getClass().isArray()){ return new ArrayWrapper(convertToObjectArray(handle)); } return handle; } public static Class getMapWrapperType(){ return MapWrapper.class; } public static Class getSetWrapperType(){ return SetWrapper.class; } public static Class getListWrapperType(){ return ListWrapper.class; } public static Class getArrayWrapperType() { return ArrayWrapper.class; } static class MapWrapper { private final Map<Object,Object> map; MapWrapper(Map map) { this.map = map; } } static class SetWrapper implements CollectionWrapper { private final Set<Object> set; SetWrapper(Set set) { this.set = set; } Set<Object> getSet() { return set; } } static class ListWrapper implements CollectionWrapper { private final List<Object> list; ListWrapper(List list) { this.list = list; } List<Object> getList() { return list; } } static class ArrayWrapper { private final Object[] array; ArrayWrapper(Object[] objects) { this.array = objects; } } //this is primarily used for copying array of primitives to array of objects //as there seems be no legal way for casting private static Object[] convertToObjectArray(Object obj) { if (obj instanceof Object[]) { return (Object[]) obj; } int arrayLength = Array.getLength(obj); Object[] retArray = new Object[arrayLength]; for (int i = 0; i < arrayLength; ++i){ retArray[i] = Array.get(obj, i); } return retArray; } }