/*
* 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.query;
import org.hypergraphdb.HGHandle;
import org.hypergraphdb.HyperGraph;
import org.hypergraphdb.HGQuery.hg;
import org.hypergraphdb.type.HGAtomType;
import org.hypergraphdb.util.HGUtils;
import org.hypergraphdb.util.Ref;
/**
* <p>
* The <code>SubsumedCondition</code> examines a given atom and is satisfied
* if that atom is subsumed by the atom specified in the condition. You can also
* provide a value instead of a HyperGraph handle by using the <code>SubsumedCondition(Object)</code>
* constructor.
* </p>
*
* @author Borislav Iordanov
*/
public class SubsumedCondition extends SubsumesImpl implements HGQueryCondition, HGAtomPredicate
{
private Ref<HGHandle> general;
private Ref<Object> generalValue;
private HGAtomPredicate impl;
private final class AtomBased implements HGAtomPredicate
{
public boolean satisfies(HyperGraph hg, HGHandle specific)
{
HGHandle specificType = hg.getType(specific);
if (generalValue.get() == null)
{
return ((HGAtomType)hg.get(hg.getType(specific))).subsumes(null, hg.get(specific));
}
else
{
HGHandle h = hg.getHandle(generalValue.get());
HGHandle generalType;
if (h == null)
generalType = hg.getTypeSystem().getTypeHandle(generalValue.get().getClass());
else
{
generalType = hg.getType(h);
if (declaredSubsumption(hg, h, specific))
return true;
}
if (!generalType.equals(specificType))
return false;
else
return ((HGAtomType)hg.get(hg.getType(specific))).subsumes(generalValue.get(), hg.get(specific));
}
}
}
private final class HandleBased implements HGAtomPredicate
{
public boolean satisfies(HyperGraph hg, HGHandle specific)
{
if (declaredSubsumption(hg, general.get(), specific))
return true;
HGHandle specificType = hg.getType(specific);
HGHandle generalType = hg.getType(general.get());
if (!generalType.equals(specificType))
return false;
else
return ((HGAtomType)hg.get(generalType)).subsumes(hg.get(general.get()), hg.get(specific));
}
}
public SubsumedCondition()
{
}
public SubsumedCondition(Object generalValue)
{
setGeneralValue(generalValue);
}
public SubsumedCondition(HGHandle general)
{
setGeneralHandle(general);
}
public Ref<HGHandle> getGeneralHandleReference()
{
return general;
}
public void setGeneralHandleReference(Ref<HGHandle> general)
{
this.general = general;
}
public HGHandle getGeneralHandle()
{
return general.get();
}
public void setGeneralHandle(HGHandle general)
{
this.general = hg.constant(general);
this.generalValue = null;
if (general != null)
impl = new HandleBased();
}
public Object getGeneralValue()
{
return generalValue.get();
}
public void setGeneralValue(Object generalValue)
{
this.generalValue = hg.constant(generalValue);
this.general = null;
if (generalValue != null)
impl = new AtomBased();
}
public final boolean satisfies(HyperGraph hg, HGHandle specific)
{
return impl.satisfies(hg, specific);
}
public int hashCode()
{
int hash = 0;
if (general != null)
hash = HGUtils.hashIt(general.get());
else if (generalValue != null)
hash = HGUtils.hashIt(generalValue.get());
return hash;
}
public boolean equals(Object x)
{
if (! (x instanceof SubsumedCondition))
return false;
else
{
SubsumedCondition c = (SubsumedCondition)x;
if (general != null)
return c.general == null ? false : HGUtils.eq(general.get(), c.general.get());
else if (generalValue != null)
return c.generalValue == null ? false : HGUtils.eq(generalValue.get(), c.generalValue.get());
else
return c.general == null && c.generalValue == null;
}
}
}