/*
* This file is part of the HyperGraphDB source distribution. This is copyrighted
* software. For permitted uses, licensing options and redistribution, please see
* the LicensingInformation file at the root level of the distribution.
*
* Copyright (c) 2005-2010 Kobrix Software, Inc. All rights reserved.
*/
package org.hypergraphdb.type;
import java.util.Collection;
import org.hypergraphdb.HGHandle;
import org.hypergraphdb.HGPersistentHandle;
import org.hypergraphdb.HyperGraph;
import org.hypergraphdb.IncidenceSetRef;
import org.hypergraphdb.LazyRef;
/**
* <p>
* A <code>CollectionType</code> instance is capable for managing collections
* of objects in the HyperGraph store. Nothing is assumed about the elements in the
* collection. In particular, the latter may be heterogenous.
* </p>
*
* @author Borislav Iordanov
*/
public class CollectionType implements HGAtomType
{
private HyperGraph graph = null;
private ObjectFactory<Collection<Object>> factory = null;
public CollectionType(ObjectFactory<Collection<Object>> factory)
{
this.factory = factory;
}
public void setHyperGraph(HyperGraph hg)
{
this.graph = hg;
}
public ObjectFactory<Collection<Object>> getFactory()
{
return factory;
}
public Object make(HGPersistentHandle handle, LazyRef<HGHandle[]> targetSet, IncidenceSetRef incidenceSet)
{
Collection<Object> result;
if (targetSet == null || targetSet.deref().length == 0)
result = factory.make();
else
result = factory.make(targetSet.deref());
TypeUtils.setValueFor(graph, handle, result);
HGPersistentHandle [] layout = graph.getStore().getLink(handle);
for (int i = 0; i < layout.length; i += 2)
{
Object current = null;
HGPersistentHandle typeHandle = layout[i];
HGPersistentHandle valueHandle = layout[i+1];
if (!typeHandle.equals(graph.getHandleFactory().nullHandle()))
{
HGAtomType type = graph.getTypeSystem().getType(typeHandle);
current = TypeUtils.makeValue(graph, valueHandle, type);
}
result.add(current);
}
return result;
}
@SuppressWarnings("unchecked")
public HGPersistentHandle store(Object instance)
{
HGPersistentHandle result = TypeUtils.getNewHandleFor(graph, instance);
Collection<Object> collection = (Collection<Object>)instance;
HGPersistentHandle [] layout = new HGPersistentHandle[collection.size()*2];
int pos = 0;
for (Object curr : collection)
{
if (curr == null)
{
layout[pos++] = graph.getHandleFactory().nullHandle();
layout[pos++] = graph.getHandleFactory().nullHandle();
}
else
{
HGHandle typeHandle = graph.getTypeSystem().getTypeHandle(curr.getClass());
layout[pos++] = graph.getPersistentHandle(typeHandle);
layout[pos++] = TypeUtils.storeValue(graph,
curr,
graph.getTypeSystem().getType(typeHandle));
}
}
graph.getStore().store(result, layout);
return result;
}
public void release(HGPersistentHandle handle)
{
// TypeUtils.releaseValue(hg, handle);
HGPersistentHandle [] layout = graph.getStore().getLink(handle);
for (int i = 0; i < layout.length; i += 2)
{
HGPersistentHandle typeHandle = layout[i];
HGPersistentHandle valueHandle = layout[i+1];
if (typeHandle.equals(graph.getHandleFactory().nullHandle()))
continue;
if (!TypeUtils.isValueReleased(graph, valueHandle))
{
HGAtomType type = graph.get(typeHandle);
TypeUtils.releaseValue(graph, type, valueHandle);
//type.release(valueHandle);
}
}
graph.getStore().removeLink(handle);
}
public boolean subsumes(Object general, Object specific)
{
return false;
}
}