/* * 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>SubsumesCondition</code> examines a given atom and is satisfied * if that atom subsumes the atom specified in the condition. * </p> * * @author Borislav Iordanov */ public class SubsumesCondition extends SubsumesImpl implements HGQueryCondition, HGAtomPredicate { private Ref<HGHandle> specific; private Ref<Object> specificValue; private HGAtomPredicate impl; private final class AtomBased implements HGAtomPredicate { public boolean satisfies(HyperGraph graph, HGHandle general) { HGHandle generalType = graph.getType(general); if (specificValue.get() == null) { return ((HGAtomType)graph.get(graph.getType(general))).subsumes(graph.get(general), null); } else { HGHandle h = graph.getHandle(specificValue.get()); HGHandle specificType; if (h == null) specificType = graph.getTypeSystem().getTypeHandle(specificValue.get().getClass()); else { specificType = graph.getType(h); if (declaredSubsumption(graph, general, h)) return true; } if (!specificType.equals(generalType)) return false; else return ((HGAtomType)graph.get(graph.getType(general))).subsumes(graph.get(general), specificValue.get()); } } } private final class HandleBased implements HGAtomPredicate { public boolean satisfies(HyperGraph graph, HGHandle general) { if (declaredSubsumption(graph, general, specific.get())) return true; HGHandle specificType = graph.getType(specific.get()); HGHandle generalType = graph.getType(general); if (!generalType.equals(specificType)) return false; else return ((HGAtomType)graph.get(generalType)).subsumes(graph.get(general), graph.get(specific.get())); } } public SubsumesCondition() { } public SubsumesCondition(Object specificValue) { setSpecificValue(specificValue); } public SubsumesCondition(HGHandle specific) { setSpecificHandle(specific); } public Ref<HGHandle> getSpecificHandleReference() { return specific; } public void setSpecificHandleReference(Ref<HGHandle> specific) { this.specific = specific; } public HGHandle getSpecificHandle() { return specific == null ? null : specific.get(); } public void setSpecificHandle(HGHandle specific) { this.specific = hg.constant(specific); this.specificValue = null; if(specific != null) impl = new HandleBased(); } public Object getSpecificValue() { return specificValue == null ? null : specificValue.get(); } public void setSpecificValue(Object specificValue) { this.specificValue = hg.constant(specificValue); this.specific = null; if (specificValue != null) impl = new AtomBased(); } public final boolean satisfies(HyperGraph hg, HGHandle general) { return impl.satisfies(hg, general); } public int hashCode() { return (specific != null) ? specific.hashCode() : specificValue.hashCode(); } public boolean equals(Object x) { if (! (x instanceof SubsumesCondition)) return false; else { SubsumesCondition c = (SubsumesCondition)x; if (specific != null) return c.specific == null ? false : HGUtils.eq(specific.get(), c.specific.get()); else if (specificValue != null) return c.specificValue == null ? false : HGUtils.eq(specificValue.get(), c.specificValue.get()); else return c.specific == null && c.specificValue == null; } } }