extensions/net.sf.basedb.varsearch/trunk/src/net/sf/basedb/varsearch/dao/Annotationtype.java

Code
Comments
Other
Rev Date Author Line
6146 23 Feb 21 nicklas 1 package net.sf.basedb.varsearch.dao;
6146 23 Feb 21 nicklas 2
6146 23 Feb 21 nicklas 3 import java.lang.reflect.Field;
6146 23 Feb 21 nicklas 4 import java.util.List;
6146 23 Feb 21 nicklas 5
6146 23 Feb 21 nicklas 6 import net.sf.basedb.core.Annotatable;
6146 23 Feb 21 nicklas 7 import net.sf.basedb.core.Annotation;
6146 23 Feb 21 nicklas 8 import net.sf.basedb.core.AnnotationSet;
6146 23 Feb 21 nicklas 9 import net.sf.basedb.core.AnnotationType;
6146 23 Feb 21 nicklas 10 import net.sf.basedb.core.DbControl;
6146 23 Feb 21 nicklas 11 import net.sf.basedb.core.Include;
6146 23 Feb 21 nicklas 12 import net.sf.basedb.core.InvalidDataException;
6146 23 Feb 21 nicklas 13 import net.sf.basedb.core.Item;
6146 23 Feb 21 nicklas 14 import net.sf.basedb.core.ItemNotFoundException;
6146 23 Feb 21 nicklas 15 import net.sf.basedb.core.ItemQuery;
6146 23 Feb 21 nicklas 16 import net.sf.basedb.core.Type;
6146 23 Feb 21 nicklas 17 import net.sf.basedb.core.query.Expression;
6146 23 Feb 21 nicklas 18 import net.sf.basedb.core.query.Expressions;
6146 23 Feb 21 nicklas 19 import net.sf.basedb.core.query.Hql;
6146 23 Feb 21 nicklas 20 import net.sf.basedb.core.query.Restrictions;
6146 23 Feb 21 nicklas 21
6146 23 Feb 21 nicklas 22 /**
6146 23 Feb 21 nicklas 23   Used to define a annotation type items.
6146 23 Feb 21 nicklas 24   
6146 23 Feb 21 nicklas 25   @author nicklas
6146 23 Feb 21 nicklas 26 */
6146 23 Feb 21 nicklas 27 public class Annotationtype 
6146 23 Feb 21 nicklas 28 {
6146 23 Feb 21 nicklas 29
6146 23 Feb 21 nicklas 30   /**
6146 23 Feb 21 nicklas 31     The "AutoProcessing" annotation which, if set, is a 
6146 23 Feb 21 nicklas 32     flag to indicate that variants should not automatically
6146 23 Feb 21 nicklas 33     be indexed.
6146 23 Feb 21 nicklas 34   */
6146 23 Feb 21 nicklas 35   public static final Annotationtype AUTO_PROCESSING = 
6146 23 Feb 21 nicklas 36     new Annotationtype("AutoProcessing", Type.STRING, false);
6146 23 Feb 21 nicklas 37
6146 23 Feb 21 nicklas 38   /**
6146 23 Feb 21 nicklas 39     Get the annotation type by name of the static constant defined in this class.
6146 23 Feb 21 nicklas 40     
6146 23 Feb 21 nicklas 41     @param cName The name of the static constant
6146 23 Feb 21 nicklas 42     @return An annotationtype object or null if not found
6146 23 Feb 21 nicklas 43   */
6146 23 Feb 21 nicklas 44   public static Annotationtype getByCName(String cName)
6146 23 Feb 21 nicklas 45   {
6146 23 Feb 21 nicklas 46     if (cName == null) return null;
6146 23 Feb 21 nicklas 47     Annotationtype type = null;
6146 23 Feb 21 nicklas 48     try
6146 23 Feb 21 nicklas 49     {
6146 23 Feb 21 nicklas 50       Field f = Annotationtype.class.getDeclaredField(cName);
6146 23 Feb 21 nicklas 51       type = (Annotationtype)f.get(null);
6146 23 Feb 21 nicklas 52     }
6146 23 Feb 21 nicklas 53     catch (NoSuchFieldException ex)
6146 23 Feb 21 nicklas 54     {}
6146 23 Feb 21 nicklas 55     catch (IllegalAccessException ex)
6146 23 Feb 21 nicklas 56     {}
6146 23 Feb 21 nicklas 57     catch (ClassCastException ex)
6146 23 Feb 21 nicklas 58     {}
6146 23 Feb 21 nicklas 59     return type;
6146 23 Feb 21 nicklas 60   }
6146 23 Feb 21 nicklas 61   
6146 23 Feb 21 nicklas 62   private final String name;
6146 23 Feb 21 nicklas 63   private final String description;
6146 23 Feb 21 nicklas 64   private final boolean disableLog;
6146 23 Feb 21 nicklas 65   private final Item[] mainType;
6146 23 Feb 21 nicklas 66   private final Type valueType;
6146 23 Feb 21 nicklas 67   
6146 23 Feb 21 nicklas 68   private int id;
6146 23 Feb 21 nicklas 69
6146 23 Feb 21 nicklas 70   /**
6146 23 Feb 21 nicklas 71     Create a new definition of an annotation type.
6146 23 Feb 21 nicklas 72     
6146 23 Feb 21 nicklas 73     @param name The name of the subtype
6146 23 Feb 21 nicklas 74     @param valueType The date type of values that can be stored 
6146 23 Feb 21 nicklas 75     @param disableLog TRUE if change history logging of annotation values should be disabled
6146 23 Feb 21 nicklas 76     @param mainType The main item type(s) of the annotation type
6146 23 Feb 21 nicklas 77   */
6146 23 Feb 21 nicklas 78   private Annotationtype(String name, Type valueType, boolean disableLog, Item... mainType)
6146 23 Feb 21 nicklas 79   {
6146 23 Feb 21 nicklas 80     this.name = name;
6146 23 Feb 21 nicklas 81     this.description = null;
6146 23 Feb 21 nicklas 82     this.valueType = valueType;
6146 23 Feb 21 nicklas 83     this.disableLog = disableLog;
6146 23 Feb 21 nicklas 84     this.mainType = mainType;
6146 23 Feb 21 nicklas 85   }
6146 23 Feb 21 nicklas 86   
6146 23 Feb 21 nicklas 87   /**
6146 23 Feb 21 nicklas 88     Create a new definition of an annotation type.
6146 23 Feb 21 nicklas 89     
6146 23 Feb 21 nicklas 90     @param name The name of the subtype
6146 23 Feb 21 nicklas 91     @param valueType The date type of values that can be stored 
6146 23 Feb 21 nicklas 92     @param disableLog TRUE if change history logging of annotation values should be disabled
6146 23 Feb 21 nicklas 93     @param mainType The main item type(s) of the annotation type
6146 23 Feb 21 nicklas 94   */
6146 23 Feb 21 nicklas 95   private Annotationtype(String name, Type valueType, boolean disableLog, String description, Item... mainType)
6146 23 Feb 21 nicklas 96   {
6146 23 Feb 21 nicklas 97     this.name = name;
6146 23 Feb 21 nicklas 98     this.description = description;
6146 23 Feb 21 nicklas 99     this.valueType = valueType;
6146 23 Feb 21 nicklas 100     this.disableLog = disableLog;
6146 23 Feb 21 nicklas 101     this.mainType = mainType;
6146 23 Feb 21 nicklas 102   }
6146 23 Feb 21 nicklas 103   
6146 23 Feb 21 nicklas 104   /**
6146 23 Feb 21 nicklas 105     Get the name of the subtype.
6146 23 Feb 21 nicklas 106   */
6146 23 Feb 21 nicklas 107   public String getName()
6146 23 Feb 21 nicklas 108   {
6146 23 Feb 21 nicklas 109     return name;
6146 23 Feb 21 nicklas 110   }
6146 23 Feb 21 nicklas 111   
6146 23 Feb 21 nicklas 112   public String getDescription()
6146 23 Feb 21 nicklas 113   {
6146 23 Feb 21 nicklas 114     return description;
6146 23 Feb 21 nicklas 115   }
6146 23 Feb 21 nicklas 116   
6146 23 Feb 21 nicklas 117   /**
6146 23 Feb 21 nicklas 118     Get the data type of the values that can be stored.
6146 23 Feb 21 nicklas 119   */
6146 23 Feb 21 nicklas 120   public Type getValueType()
6146 23 Feb 21 nicklas 121   {
6146 23 Feb 21 nicklas 122     return valueType;
6146 23 Feb 21 nicklas 123   }
6146 23 Feb 21 nicklas 124   
6146 23 Feb 21 nicklas 125   /**
6146 23 Feb 21 nicklas 126     Should change history logging be disabled or not for annotation values.
6146 23 Feb 21 nicklas 127     @since 2.16
6146 23 Feb 21 nicklas 128   */
6146 23 Feb 21 nicklas 129   public boolean getDisableChangeHistoryLog()
6146 23 Feb 21 nicklas 130   {
6146 23 Feb 21 nicklas 131     return disableLog;
6146 23 Feb 21 nicklas 132   }
6146 23 Feb 21 nicklas 133   
6146 23 Feb 21 nicklas 134   /**
6146 23 Feb 21 nicklas 135     Get the item type on which this annotation type can be used.
6146 23 Feb 21 nicklas 136   */
6146 23 Feb 21 nicklas 137   public Item[] getMainType()
6146 23 Feb 21 nicklas 138   {
6146 23 Feb 21 nicklas 139     return mainType;
6146 23 Feb 21 nicklas 140   }
6146 23 Feb 21 nicklas 141   
6146 23 Feb 21 nicklas 142   /**
6146 23 Feb 21 nicklas 143     Load the underlying annotation type. If it doesn't exists and exception is thrown.
6146 23 Feb 21 nicklas 144     
6146 23 Feb 21 nicklas 145     @param dc The DbControl to use for database access
6146 23 Feb 21 nicklas 146     @return An AnnotationType object
6146 23 Feb 21 nicklas 147   */
6146 23 Feb 21 nicklas 148   public AnnotationType load(DbControl dc)
6146 23 Feb 21 nicklas 149   {
6146 23 Feb 21 nicklas 150     AnnotationType type = null;
6146 23 Feb 21 nicklas 151     if (id == 0)
6146 23 Feb 21 nicklas 152     {
6146 23 Feb 21 nicklas 153       List<AnnotationType> result = list(dc);
6146 23 Feb 21 nicklas 154       if (result.size() == 0)
6146 23 Feb 21 nicklas 155       {
6146 23 Feb 21 nicklas 156         throw new ItemNotFoundException("AnnotationType["+name+"]");
6146 23 Feb 21 nicklas 157       }
6146 23 Feb 21 nicklas 158       else if (result.size() > 1)
6146 23 Feb 21 nicklas 159       {
6146 23 Feb 21 nicklas 160         throw new InvalidDataException("Found > 1 AnnotationType["+name+"]");
6146 23 Feb 21 nicklas 161       }
6146 23 Feb 21 nicklas 162       type = result.get(0);
6146 23 Feb 21 nicklas 163       id = type.getId();
6146 23 Feb 21 nicklas 164     }
6146 23 Feb 21 nicklas 165     else
6146 23 Feb 21 nicklas 166     {
6146 23 Feb 21 nicklas 167       type = AnnotationType.getById(dc, id);
6146 23 Feb 21 nicklas 168     }
6146 23 Feb 21 nicklas 169     return type;
6146 23 Feb 21 nicklas 170   }
6146 23 Feb 21 nicklas 171   
6146 23 Feb 21 nicklas 172   /**
6146 23 Feb 21 nicklas 173     Load the annotation type as a BASE item. Same as {@link #load(DbControl)} but return null
6146 23 Feb 21 nicklas 174     if no BASE item is found instead of throwing an exception.
6146 23 Feb 21 nicklas 175     @param dc The DbControl to use for database access
6146 23 Feb 21 nicklas 176     @return An AnnotationType object
6146 23 Feb 21 nicklas 177   */
6146 23 Feb 21 nicklas 178   public AnnotationType get(DbControl dc)
6146 23 Feb 21 nicklas 179   {
6146 23 Feb 21 nicklas 180     AnnotationType type = null;
6146 23 Feb 21 nicklas 181     if (id == 0)
6146 23 Feb 21 nicklas 182     {
6146 23 Feb 21 nicklas 183       List<AnnotationType> result = list(dc);
6146 23 Feb 21 nicklas 184       if (result.size() == 1)
6146 23 Feb 21 nicklas 185       {
6146 23 Feb 21 nicklas 186         type = result.get(0);
6146 23 Feb 21 nicklas 187         id = type.getId();
6146 23 Feb 21 nicklas 188       }
6146 23 Feb 21 nicklas 189     }
6146 23 Feb 21 nicklas 190     else
6146 23 Feb 21 nicklas 191     {
6146 23 Feb 21 nicklas 192       type = AnnotationType.getById(dc, id);
6146 23 Feb 21 nicklas 193     }
6146 23 Feb 21 nicklas 194     return type;
6146 23 Feb 21 nicklas 195   }
6146 23 Feb 21 nicklas 196
6146 23 Feb 21 nicklas 197   /**
6146 23 Feb 21 nicklas 198     List all annotation types registered in BASE with a name and main item type 
6146 23 Feb 21 nicklas 199     matching this annotation type definition. Normally, only a single annotation
6146 23 Feb 21 nicklas 200     type should be returned.
6146 23 Feb 21 nicklas 201   */
6146 23 Feb 21 nicklas 202   public List<AnnotationType> list(DbControl dc)
6146 23 Feb 21 nicklas 203   {
6146 23 Feb 21 nicklas 204     ItemQuery<AnnotationType> query = AnnotationType.getQuery(null);
6146 23 Feb 21 nicklas 205     query.restrict(Restrictions.eq(Hql.property("name"), Expressions.parameter("name", name, Type.STRING)));
6146 23 Feb 21 nicklas 206     
6146 23 Feb 21 nicklas 207     Item[] mt = getMainType();
6146 23 Feb 21 nicklas 208     Expression[] mainTypes = new Expression[mt.length];
6146 23 Feb 21 nicklas 209     for (int i = 0; i < mainTypes.length; ++i)
6146 23 Feb 21 nicklas 210     {
6146 23 Feb 21 nicklas 211       mainTypes[i] = Expressions.integer(mt[i].getValue());
6146 23 Feb 21 nicklas 212     }
6146 23 Feb 21 nicklas 213     if (mainTypes.length > 0)
6146 23 Feb 21 nicklas 214     {
6146 23 Feb 21 nicklas 215       query.joinPermanent(Hql.innerJoin("itemTypes", "it"));
6146 23 Feb 21 nicklas 216       query.restrictPermanent(Restrictions.in(Hql.alias("it"), mainTypes));
6146 23 Feb 21 nicklas 217     }
6146 23 Feb 21 nicklas 218
6146 23 Feb 21 nicklas 219     query.include(Include.ALL);
6146 23 Feb 21 nicklas 220     query.setDistinct(true);
6146 23 Feb 21 nicklas 221     return query.list(dc);
6146 23 Feb 21 nicklas 222   }
6146 23 Feb 21 nicklas 223
6146 23 Feb 21 nicklas 224   /**
6146 23 Feb 21 nicklas 225     Check if the item already has an annotation value for this
6146 23 Feb 21 nicklas 226     annotation type.
6146 23 Feb 21 nicklas 227   */
6146 23 Feb 21 nicklas 228   public boolean hasAnnotation(DbControl dc, Annotatable item)
6146 23 Feb 21 nicklas 229   {
6146 23 Feb 21 nicklas 230     if (item == null) return false;
6146 23 Feb 21 nicklas 231     AnnotationType at = load(dc);
6146 23 Feb 21 nicklas 232     if (!item.isAnnotated()) return false;
6146 23 Feb 21 nicklas 233     AnnotationSet as = item.getAnnotationSet();
6146 23 Feb 21 nicklas 234     return as.hasAnnotation(at, Annotation.Source.PRIMARY);
6146 23 Feb 21 nicklas 235   }
6146 23 Feb 21 nicklas 236   
6146 23 Feb 21 nicklas 237   /**
6146 23 Feb 21 nicklas 238     Get the annotation value (single) for this annotation type from the
6146 23 Feb 21 nicklas 239     annotatable item.
6146 23 Feb 21 nicklas 240     @return The value, or null if the item is not annotated
6146 23 Feb 21 nicklas 241   */
6163 05 Mar 21 nicklas 242   @SuppressWarnings("unchecked")
6163 05 Mar 21 nicklas 243   public <T> T getAnnotationValue(DbControl dc, Annotatable item)
6146 23 Feb 21 nicklas 244   {
6146 23 Feb 21 nicklas 245     if (item == null) return null;
6146 23 Feb 21 nicklas 246     AnnotationType at = load(dc);
6146 23 Feb 21 nicklas 247     if (!item.isAnnotated()) return null;
6146 23 Feb 21 nicklas 248     AnnotationSet as = item.getAnnotationSet();
6146 23 Feb 21 nicklas 249     if (!as.hasAnnotation(at, Annotation.Source.PRIMARY)) return null;
6163 05 Mar 21 nicklas 250     return (T)as.getAnnotation(at).getValues().get(0);
6146 23 Feb 21 nicklas 251   }
6146 23 Feb 21 nicklas 252
6146 23 Feb 21 nicklas 253   /**
6146 23 Feb 21 nicklas 254      Set a (single) annotation value on an item. If the value is null the annotation
6146 23 Feb 21 nicklas 255      will be removed.
6146 23 Feb 21 nicklas 256      @return TRUE if the existing annotation value was changed, FALSE if not
6146 23 Feb 21 nicklas 257   */
6146 23 Feb 21 nicklas 258   public boolean setAnnotationValue(DbControl dc, Annotatable item, Object value)
6146 23 Feb 21 nicklas 259   {
6146 23 Feb 21 nicklas 260     AnnotationType at = load(dc);
6146 23 Feb 21 nicklas 261     boolean changed = false;
6146 23 Feb 21 nicklas 262     if (value == null)
6146 23 Feb 21 nicklas 263     {
6146 23 Feb 21 nicklas 264       if (item.isAnnotated() && item.getAnnotationSet().hasAnnotation(at, Annotation.Source.PRIMARY))
6146 23 Feb 21 nicklas 265       {
6146 23 Feb 21 nicklas 266         item.getAnnotationSet().removeAnnotation(at);
6146 23 Feb 21 nicklas 267         changed = true;
6146 23 Feb 21 nicklas 268       }
6146 23 Feb 21 nicklas 269     }
6146 23 Feb 21 nicklas 270     else
6146 23 Feb 21 nicklas 271     {
6146 23 Feb 21 nicklas 272       Type valueType = at.getValueType();
6146 23 Feb 21 nicklas 273       if (valueType.isNumerical() && value instanceof Number)
6146 23 Feb 21 nicklas 274       {
6146 23 Feb 21 nicklas 275         value = valueType.convertNumber((Number)value);
6146 23 Feb 21 nicklas 276       }
6146 23 Feb 21 nicklas 277       changed = item.getAnnotationSet().getAnnotation(at).setValueIfDifferent(value, null);
6146 23 Feb 21 nicklas 278     }
6146 23 Feb 21 nicklas 279     return changed;
6146 23 Feb 21 nicklas 280   }
6146 23 Feb 21 nicklas 281
6146 23 Feb 21 nicklas 282
6146 23 Feb 21 nicklas 283 }