src/core/net/sf/basedb/util/parser/DefaultItemFunction.java

Code
Comments
Other
Rev Date Author Line
5899 06 Dec 11 nicklas 1 /**
5899 06 Dec 11 nicklas 2   $Id$
5899 06 Dec 11 nicklas 3
5899 06 Dec 11 nicklas 4   Copyright (C) 2011 Nicklas Nordborg
5899 06 Dec 11 nicklas 5
5899 06 Dec 11 nicklas 6   This file is part of BASE - BioArray Software Environment.
5899 06 Dec 11 nicklas 7   Available at http://base.thep.lu.se/
5899 06 Dec 11 nicklas 8
5899 06 Dec 11 nicklas 9   BASE is free software; you can redistribute it and/or
5899 06 Dec 11 nicklas 10   modify it under the terms of the GNU General Public License
5899 06 Dec 11 nicklas 11   as published by the Free Software Foundation; either version 3
5899 06 Dec 11 nicklas 12   of the License, or (at your option) any later version.
5899 06 Dec 11 nicklas 13
5899 06 Dec 11 nicklas 14   BASE is distributed in the hope that it will be useful,
5899 06 Dec 11 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
5899 06 Dec 11 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5899 06 Dec 11 nicklas 17   GNU General Public License for more details.
5899 06 Dec 11 nicklas 18
5899 06 Dec 11 nicklas 19   You should have received a copy of the GNU General Public License
5899 06 Dec 11 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
5899 06 Dec 11 nicklas 21 */
5899 06 Dec 11 nicklas 22 package net.sf.basedb.util.parser;
5899 06 Dec 11 nicklas 23
5899 06 Dec 11 nicklas 24 import java.util.HashMap;
5899 06 Dec 11 nicklas 25 import java.util.List;
5899 06 Dec 11 nicklas 26 import java.util.Map;
5899 06 Dec 11 nicklas 27 import java.util.Stack;
5899 06 Dec 11 nicklas 28
5899 06 Dec 11 nicklas 29 import org.nfunk.jep.ParseException;
5899 06 Dec 11 nicklas 30
7611 01 Mar 19 nicklas 31 import net.sf.basedb.core.BasicItem;
5899 06 Dec 11 nicklas 32 import net.sf.basedb.core.DbControl;
5899 06 Dec 11 nicklas 33 import net.sf.basedb.core.Item;
5899 06 Dec 11 nicklas 34 import net.sf.basedb.core.ItemSubtype;
5899 06 Dec 11 nicklas 35 import net.sf.basedb.core.Nameable;
5899 06 Dec 11 nicklas 36 import net.sf.basedb.core.Project;
5899 06 Dec 11 nicklas 37 import net.sf.basedb.util.Values;
5899 06 Dec 11 nicklas 38 import net.sf.basedb.util.jep.JepFunction;
5899 06 Dec 11 nicklas 39
5899 06 Dec 11 nicklas 40 /**
5899 06 Dec 11 nicklas 41   JEP function that can be used to return the name of a default item in
5899 06 Dec 11 nicklas 42   a project. The constructor need to specify the project and the type
5899 06 Dec 11 nicklas 43   of item to look for. Use 'default()' or 'default(col("header"))' in the
5899 06 Dec 11 nicklas 44   JEP expression to use this function. The first variant will always
5899 06 Dec 11 nicklas 45   return the default item if one exists for the project. The second
5899 06 Dec 11 nicklas 46   variant will return the default item only if the 'col("header")' part
5899 06 Dec 11 nicklas 47   is null or an empty string.
5899 06 Dec 11 nicklas 48   <p>
5899 06 Dec 11 nicklas 49   Before this function is used the {@link #setCurrentSubtype(ItemSubtype)}
5899 06 Dec 11 nicklas 50   can be called to limit the search to items with a specific subtype. If
5899 06 Dec 11 nicklas 51   there is more than one matching item in a project, it is undefined which
5899 06 Dec 11 nicklas 52   one is returned, but multiple uses of this function will return the same 
5899 06 Dec 11 nicklas 53   item.
5899 06 Dec 11 nicklas 54
5899 06 Dec 11 nicklas 55   @author Nicklas
5899 06 Dec 11 nicklas 56   @since 3.1
5899 06 Dec 11 nicklas 57   @base.modified $Date$
5899 06 Dec 11 nicklas 58 */
5899 06 Dec 11 nicklas 59 public class DefaultItemFunction<T extends Nameable>
5899 06 Dec 11 nicklas 60   implements JepFunction
5899 06 Dec 11 nicklas 61 {
5899 06 Dec 11 nicklas 62
5899 06 Dec 11 nicklas 63   private final DbControl dc;
5899 06 Dec 11 nicklas 64   private final Project project;
5899 06 Dec 11 nicklas 65   private final Item itemType;
5899 06 Dec 11 nicklas 66   private ItemSubtype subtype;
5899 06 Dec 11 nicklas 67   private int numParameters;
5899 06 Dec 11 nicklas 68   private Map<Object, T> itemCache;
5899 06 Dec 11 nicklas 69   
5899 06 Dec 11 nicklas 70   /**
5899 06 Dec 11 nicklas 71     Create a new function instance.
5899 06 Dec 11 nicklas 72     @param dc The DbControl to use when loading items from the database
5899 06 Dec 11 nicklas 73     @param project The project (null is allowed)
5899 06 Dec 11 nicklas 74     @param itemType The type of item to look for
5899 06 Dec 11 nicklas 75   */
5899 06 Dec 11 nicklas 76   public DefaultItemFunction(DbControl dc, Project project, Item itemType)
5899 06 Dec 11 nicklas 77   {
5899 06 Dec 11 nicklas 78     this.dc = dc;
5899 06 Dec 11 nicklas 79     this.project = project;
5899 06 Dec 11 nicklas 80     this.itemType = itemType;
5899 06 Dec 11 nicklas 81     this.itemCache = new HashMap<Object, T>();
5899 06 Dec 11 nicklas 82   }
5899 06 Dec 11 nicklas 83   
5899 06 Dec 11 nicklas 84   
5899 06 Dec 11 nicklas 85   /*
5899 06 Dec 11 nicklas 86     From the JepFunction interface
5899 06 Dec 11 nicklas 87     -------------------------------------------
5899 06 Dec 11 nicklas 88   */
5899 06 Dec 11 nicklas 89   /**
5899 06 Dec 11 nicklas 90     @return The string "default"
5899 06 Dec 11 nicklas 91   */
6127 14 Sep 12 nicklas 92   @Override
5899 06 Dec 11 nicklas 93   public String getFunctionName()
5899 06 Dec 11 nicklas 94   {
5899 06 Dec 11 nicklas 95     return "default";
5899 06 Dec 11 nicklas 96   }
5899 06 Dec 11 nicklas 97   // -------------------------------------------
5899 06 Dec 11 nicklas 98
5899 06 Dec 11 nicklas 99   /*
5899 06 Dec 11 nicklas 100     From the PostfixMathCommandI interface
5899 06 Dec 11 nicklas 101     -------------------------------------------
5899 06 Dec 11 nicklas 102   */
5899 06 Dec 11 nicklas 103
5899 06 Dec 11 nicklas 104   @Override
5899 06 Dec 11 nicklas 105   public int getNumberOfParameters()
5899 06 Dec 11 nicklas 106   {
5899 06 Dec 11 nicklas 107     return -1; // We accept 0 or 1 parameter
5899 06 Dec 11 nicklas 108   }
5899 06 Dec 11 nicklas 109   
5899 06 Dec 11 nicklas 110   @Override
5899 06 Dec 11 nicklas 111   public void setCurNumberOfParameters(int n)
5899 06 Dec 11 nicklas 112   {
5899 06 Dec 11 nicklas 113     this.numParameters = n;
5899 06 Dec 11 nicklas 114   }
5899 06 Dec 11 nicklas 115
5899 06 Dec 11 nicklas 116   @Override
5899 06 Dec 11 nicklas 117   public boolean checkNumberOfParameters(int n)
5899 06 Dec 11 nicklas 118   {
5899 06 Dec 11 nicklas 119     return n == 0 || n == 1;
5899 06 Dec 11 nicklas 120   }
5899 06 Dec 11 nicklas 121
6875 20 Apr 15 nicklas 122   @SuppressWarnings({"unchecked", "rawtypes"})
5899 06 Dec 11 nicklas 123   @Override
5899 06 Dec 11 nicklas 124   public void run(Stack stack) 
5899 06 Dec 11 nicklas 125     throws ParseException
5899 06 Dec 11 nicklas 126   {
5899 06 Dec 11 nicklas 127     if (stack == null) 
5899 06 Dec 11 nicklas 128     {
5899 06 Dec 11 nicklas 129       throw new ParseException("Stack is null");
5899 06 Dec 11 nicklas 130     }
5899 06 Dec 11 nicklas 131
5899 06 Dec 11 nicklas 132     Object param = numParameters == 1 ? stack.pop() : null;
5899 06 Dec 11 nicklas 133     // If there is no parameter or if it is empty...
5899 06 Dec 11 nicklas 134     if (param == null || Values.getStringOrNull(param.toString()) == null)
5899 06 Dec 11 nicklas 135     {
5899 06 Dec 11 nicklas 136       // Find the default item and get the name...
5899 06 Dec 11 nicklas 137       T item = findDefaultItem();
5899 06 Dec 11 nicklas 138       param = item == null ? null : item.getName();
5899 06 Dec 11 nicklas 139     }
5899 06 Dec 11 nicklas 140     // Finally, put the result back on the stack
5899 06 Dec 11 nicklas 141     stack.push(param);
5899 06 Dec 11 nicklas 142   }
5899 06 Dec 11 nicklas 143   // -------------------------------------------
5899 06 Dec 11 nicklas 144   
5899 06 Dec 11 nicklas 145   /**
5899 06 Dec 11 nicklas 146     Find a default item. If a subtype has been set
5899 06 Dec 11 nicklas 147     with {@link #setCurrentSubtype(ItemSubtype)} the
5899 06 Dec 11 nicklas 148     {@link Project#findDefaultItems(DbControl, ItemSubtype, boolean)} 
5899 06 Dec 11 nicklas 149     method is used in non-strict mode, otherwise the 
5899 06 Dec 11 nicklas 150     {@link Project#findDefaultItems(DbControl, Item, boolean)}
5899 06 Dec 11 nicklas 151     is used in strict mode.
5899 06 Dec 11 nicklas 152     @return A matching default item or null if none could be found
5899 06 Dec 11 nicklas 153   */
5899 06 Dec 11 nicklas 154   @SuppressWarnings("unchecked")
5899 06 Dec 11 nicklas 155   public T findDefaultItem()
5899 06 Dec 11 nicklas 156   {
5899 06 Dec 11 nicklas 157     if (project == null) return null;
5899 06 Dec 11 nicklas 158     T item = null;
5899 06 Dec 11 nicklas 159     if (itemCache.containsKey(subtype))
5899 06 Dec 11 nicklas 160     {
5899 06 Dec 11 nicklas 161       item = itemCache.get(subtype);
5899 06 Dec 11 nicklas 162     }
5899 06 Dec 11 nicklas 163     else
5899 06 Dec 11 nicklas 164     {
7611 01 Mar 19 nicklas 165       List<BasicItem> items = subtype == null ? 
7611 01 Mar 19 nicklas 166         project.findDefaultItems(dc, itemType, true) :
7611 01 Mar 19 nicklas 167         project.findDefaultItems(dc, subtype, false);
7611 01 Mar 19 nicklas 168       item = items.size() > 0 ? (T)items.get(0) : null;
5899 06 Dec 11 nicklas 169       itemCache.put(subtype, item);
5899 06 Dec 11 nicklas 170     }
5899 06 Dec 11 nicklas 171     return item;
5899 06 Dec 11 nicklas 172   }
5899 06 Dec 11 nicklas 173   
5899 06 Dec 11 nicklas 174   /**
5899 06 Dec 11 nicklas 175     Set the current subtype to use when looking for default items.
5899 06 Dec 11 nicklas 176   */
5899 06 Dec 11 nicklas 177   public void setCurrentSubtype(ItemSubtype subtype)
5899 06 Dec 11 nicklas 178   {
5899 06 Dec 11 nicklas 179     this.subtype = subtype;
5899 06 Dec 11 nicklas 180   }
5899 06 Dec 11 nicklas 181 }