extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/query/AnyToAnyRestriction.java

Code
Comments
Other
Rev Date Author Line
2877 30 Oct 14 nicklas 1 package net.sf.basedb.reggie.query;
2877 30 Oct 14 nicklas 2
2877 30 Oct 14 nicklas 3 import java.util.Collection;
5760 26 Nov 19 nicklas 4 import java.util.Collections;
2877 30 Oct 14 nicklas 5
2877 30 Oct 14 nicklas 6 import net.sf.basedb.core.DbControl;
3051 17 Dec 14 nicklas 7 import net.sf.basedb.core.Item;
2877 30 Oct 14 nicklas 8 import net.sf.basedb.core.Type;
5760 26 Nov 19 nicklas 9 import net.sf.basedb.core.query.Expressions;
5760 26 Nov 19 nicklas 10 import net.sf.basedb.core.query.Hql;
2877 30 Oct 14 nicklas 11 import net.sf.basedb.core.query.Query;
2877 30 Oct 14 nicklas 12 import net.sf.basedb.core.query.QueryElement;
2877 30 Oct 14 nicklas 13 import net.sf.basedb.core.query.Restriction;
5760 26 Nov 19 nicklas 14 import net.sf.basedb.core.query.Restrictions;
2877 30 Oct 14 nicklas 15 import net.sf.basedb.util.EqualsHelper;
2877 30 Oct 14 nicklas 16
2877 30 Oct 14 nicklas 17
2877 30 Oct 14 nicklas 18 /**
2877 30 Oct 14 nicklas 19   Expression that can be used to filter on the existence or non-existence
2877 30 Oct 14 nicklas 20   of a named any-to-any link.
2877 30 Oct 14 nicklas 21
2877 30 Oct 14 nicklas 22   @author nicklas
2877 30 Oct 14 nicklas 23   @since 2.18
2877 30 Oct 14 nicklas 24 */
2877 30 Oct 14 nicklas 25 public class AnyToAnyRestriction 
2877 30 Oct 14 nicklas 26   implements Restriction 
2877 30 Oct 14 nicklas 27 {
2877 30 Oct 14 nicklas 28
2877 30 Oct 14 nicklas 29   /**
2877 30 Oct 14 nicklas 30     Create a restriction that restrict a query to return
2877 30 Oct 14 nicklas 31     items that has a linked item with the given link name.
2877 30 Oct 14 nicklas 32   */
3051 17 Dec 14 nicklas 33   public static AnyToAnyRestriction exists(String linkName, Item linkedTo)
2877 30 Oct 14 nicklas 34   {
5760 26 Nov 19 nicklas 35     Restriction link = linkedTo == null ? null :
5760 26 Nov 19 nicklas 36       Restrictions.eq(Hql.property("at", "toType"), Expressions.integer(linkedTo.getValue()));
5760 26 Nov 19 nicklas 37     return new AnyToAnyRestriction(linkName, link, true);
2877 30 Oct 14 nicklas 38   }
5760 26 Nov 19 nicklas 39
5760 26 Nov 19 nicklas 40   /**
5760 26 Nov 19 nicklas 41     Create a restriction that restrict a query to return
5760 26 Nov 19 nicklas 42     items that has a linked item with the given link name.
5760 26 Nov 19 nicklas 43     An optional restriction can be used to limit the query
5760 26 Nov 19 nicklas 44     to on the linked item (use "at" as prefix in the HQL).
5760 26 Nov 19 nicklas 45     @since 4.24.1
5760 26 Nov 19 nicklas 46   */
5760 26 Nov 19 nicklas 47   public static AnyToAnyRestriction exists(String linkName, Restriction restriction)
5760 26 Nov 19 nicklas 48   {
5760 26 Nov 19 nicklas 49     return new AnyToAnyRestriction(linkName, restriction, true);
5760 26 Nov 19 nicklas 50   }
5760 26 Nov 19 nicklas 51
2877 30 Oct 14 nicklas 52   
2877 30 Oct 14 nicklas 53   /**
2877 30 Oct 14 nicklas 54     Create a restriction that restrict a query to return
2877 30 Oct 14 nicklas 55     items that is missing a linked item with the given link 
2877 30 Oct 14 nicklas 56     name.
2877 30 Oct 14 nicklas 57   */
3051 17 Dec 14 nicklas 58   public static AnyToAnyRestriction missing(String linkName, Item linkedTo)
2877 30 Oct 14 nicklas 59   {
5760 26 Nov 19 nicklas 60     Restriction link = linkedTo == null ? null :
5760 26 Nov 19 nicklas 61         Restrictions.eq(Hql.property("at", "toType"), Expressions.integer(linkedTo.getValue()));
5760 26 Nov 19 nicklas 62     return new AnyToAnyRestriction(linkName, link, false);
2877 30 Oct 14 nicklas 63   }
2877 30 Oct 14 nicklas 64   
2877 30 Oct 14 nicklas 65   private final String parameterName;
5760 26 Nov 19 nicklas 66   private final Restriction linkRestriction;
2877 30 Oct 14 nicklas 67   private final String linkName;
2877 30 Oct 14 nicklas 68   private final boolean hasLink;
2877 30 Oct 14 nicklas 69   
5760 26 Nov 19 nicklas 70   private AnyToAnyRestriction(String linkName, Restriction linkRestriction, boolean hasLink) 
2877 30 Oct 14 nicklas 71   {
2877 30 Oct 14 nicklas 72     this.linkName = linkName;
2877 30 Oct 14 nicklas 73     this.hasLink = hasLink;
2877 30 Oct 14 nicklas 74     this.parameterName = "LN" + System.identityHashCode(this);
5760 26 Nov 19 nicklas 75     this.linkRestriction = linkRestriction;
2877 30 Oct 14 nicklas 76   }
2877 30 Oct 14 nicklas 77   
2877 30 Oct 14 nicklas 78   @Override
2877 30 Oct 14 nicklas 79   public String toQl(Query query, DbControl dc)
2877 30 Oct 14 nicklas 80   {
2877 30 Oct 14 nicklas 81     query.setParameter(parameterName, linkName, Type.STRING);
5760 26 Nov 19 nicklas 82     return query.getRootAlias() + (hasLink ? ".id = ANY" : ".id <> ALL") + getSubQuery(query, dc);
2877 30 Oct 14 nicklas 83   }
2877 30 Oct 14 nicklas 84
2877 30 Oct 14 nicklas 85   @Override
2877 30 Oct 14 nicklas 86   public Collection<? extends QueryElement> getChildren()
2877 30 Oct 14 nicklas 87   {
5760 26 Nov 19 nicklas 88     return linkRestriction != null ? Collections.singleton(linkRestriction) : null;
2877 30 Oct 14 nicklas 89   }
2877 30 Oct 14 nicklas 90
5760 26 Nov 19 nicklas 91   private String getSubQuery(Query query, DbControl dc)
5760 26 Nov 19 nicklas 92   {
5760 26 Nov 19 nicklas 93     StringBuilder sb = new StringBuilder();
5760 26 Nov 19 nicklas 94     sb.append("(SELECT at.fromId FROM AnyToAnyData at WHERE at.name = :");
5760 26 Nov 19 nicklas 95     sb.append(parameterName);
5760 26 Nov 19 nicklas 96     if (linkRestriction != null)
5760 26 Nov 19 nicklas 97     {
5760 26 Nov 19 nicklas 98       if (query == null)
5760 26 Nov 19 nicklas 99       {
5760 26 Nov 19 nicklas 100         sb.append(" AND ").append(linkRestriction.toString());
5760 26 Nov 19 nicklas 101       }
5760 26 Nov 19 nicklas 102       else
5760 26 Nov 19 nicklas 103       {
5760 26 Nov 19 nicklas 104         sb.append(" AND ").append(linkRestriction.toQl(query, dc));
5760 26 Nov 19 nicklas 105       }
5760 26 Nov 19 nicklas 106     }
5760 26 Nov 19 nicklas 107     sb.append(")");
5760 26 Nov 19 nicklas 108     return sb.toString();
5760 26 Nov 19 nicklas 109   }
2877 30 Oct 14 nicklas 110   
2877 30 Oct 14 nicklas 111   @Override
2877 30 Oct 14 nicklas 112   public String toString()
2877 30 Oct 14 nicklas 113   {
5760 26 Nov 19 nicklas 114     return (hasLink ? "id = ANY" : "id <> ALL") + getSubQuery(null, null);
2877 30 Oct 14 nicklas 115   }
2877 30 Oct 14 nicklas 116   
2877 30 Oct 14 nicklas 117   /**
2877 30 Oct 14 nicklas 118     This expression is equal to another AnyToAnyRestriction if their 
2877 30 Oct 14 nicklas 119     named link and 'hasLink' parameter is the same.
2877 30 Oct 14 nicklas 120   */
2877 30 Oct 14 nicklas 121   @Override
2877 30 Oct 14 nicklas 122   public boolean equals(Object other)
2877 30 Oct 14 nicklas 123   {
2877 30 Oct 14 nicklas 124     if (this == other) return true;
2877 30 Oct 14 nicklas 125     if ((other == null) || (super.getClass() != other.getClass())) return false;
2877 30 Oct 14 nicklas 126     AnyToAnyRestriction o = (AnyToAnyRestriction)other;
2877 30 Oct 14 nicklas 127     return EqualsHelper.equals(linkName, o.linkName) && hasLink == o.hasLink;
2877 30 Oct 14 nicklas 128   }
2877 30 Oct 14 nicklas 129   
2877 30 Oct 14 nicklas 130   @Override
2877 30 Oct 14 nicklas 131   public int hashCode()
2877 30 Oct 14 nicklas 132   {
2877 30 Oct 14 nicklas 133     return EqualsHelper.hashCode(linkName) + getClass().hashCode();
2877 30 Oct 14 nicklas 134   }
2877 30 Oct 14 nicklas 135
2877 30 Oct 14 nicklas 136   
2877 30 Oct 14 nicklas 137 }