/*
* 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.atom;
import org.hypergraphdb.HGException;
import org.hypergraphdb.HGHandle;
import org.hypergraphdb.HGLink;
import org.hypergraphdb.HGPersistentHandle;
import org.hypergraphdb.HyperGraph;
import org.hypergraphdb.IncidenceSetRef;
import org.hypergraphdb.LazyRef;
import org.hypergraphdb.type.HGAtomTypeBase;
/**
*
* <p>
* Represents the type a "semantic" relationship. It carries the
* name of the relationships and the types of its arguments. The latter
* are simply the target set of a <code>HGRelType</code> instance.
* </p>
*
* @author Borislav Iordanov
*
*/
public class HGRelType extends HGAtomTypeBase implements HGLink
{
private String name;
private HGHandle [] targetTypes;
private void init(String name, HGHandle...targetTypes)
{
this.name = name;
if (targetTypes == null)
targetTypes = HyperGraph.EMPTY_HANDLE_SET;
this.targetTypes = targetTypes;
}
public HGRelType()
{
init("");
}
public HGRelType(String name)
{
init(name);
}
public HGRelType(HGHandle...targetTypes)
{
init("", targetTypes);
}
public HGRelType(String name, HGHandle...targetTypes)
{
init(name, targetTypes);
}
public Object make(HGPersistentHandle handle, LazyRef<HGHandle[]> targetSet, IncidenceSetRef incidenceSet)
{
if (targetSet == null)
{
if (targetTypes != null && targetTypes.length > 0)
throw new HGException("HGRelType.make: expected a target set of size " +
targetTypes.length + " but got a null.");
}
else if (targetSet.deref().length != targetTypes.length)
throw new HGException("HGRelType.make: expected a target set of size " +
targetTypes.length + " but got size " + targetSet.deref().length);
return new HGRel(name, targetSet.deref());
}
public void release(HGPersistentHandle handle)
{
}
public HGPersistentHandle store(Object instance)
{
// there's no value of the relation per se, it's only a link
// that's simply strongly typed....and we don't bother checking
// the types of the target atoms for now
return graph.getHandleFactory().nullHandle();
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getArity()
{
return targetTypes.length;
}
public HGHandle getTargetAt(int i)
{
return targetTypes[i];
}
public void notifyTargetHandleUpdate(int i, HGHandle handle)
{
targetTypes[i] = handle;
}
public void notifyTargetRemoved(int i)
{
HGHandle [] newOutgoing = new HGHandle[targetTypes.length - 1];
System.arraycopy(targetTypes, 0, newOutgoing, 0, i);
System.arraycopy(targetTypes, i + 1, newOutgoing, i, targetTypes.length - i -1);
targetTypes = newOutgoing;
}
public int hashCode()
{
return name == null ? 0 : name.hashCode();
}
public boolean equals(Object other)
{
if (! (other instanceof HGRelType))
return false;
HGRelType rt = (HGRelType)other;
if (!rt.getName().equals(name))
return false;
else if (targetTypes == rt.targetTypes)
return true;
else if (targetTypes.length != rt.targetTypes.length)
return false;
for (int i = 0; i < targetTypes.length; i++)
if (!targetTypes[i].equals(rt.targetTypes[i]))
return false;
return true;
}
}