5899 |
06 Dec 11 |
nicklas |
1 |
/** |
5899 |
06 Dec 11 |
nicklas |
$Id$ |
5899 |
06 Dec 11 |
nicklas |
3 |
|
5899 |
06 Dec 11 |
nicklas |
Copyright (C) 2011 Nicklas Nordborg |
5899 |
06 Dec 11 |
nicklas |
5 |
|
5899 |
06 Dec 11 |
nicklas |
This file is part of BASE - BioArray Software Environment. |
5899 |
06 Dec 11 |
nicklas |
Available at http://base.thep.lu.se/ |
5899 |
06 Dec 11 |
nicklas |
8 |
|
5899 |
06 Dec 11 |
nicklas |
BASE is free software; you can redistribute it and/or |
5899 |
06 Dec 11 |
nicklas |
modify it under the terms of the GNU General Public License |
5899 |
06 Dec 11 |
nicklas |
as published by the Free Software Foundation; either version 3 |
5899 |
06 Dec 11 |
nicklas |
of the License, or (at your option) any later version. |
5899 |
06 Dec 11 |
nicklas |
13 |
|
5899 |
06 Dec 11 |
nicklas |
BASE is distributed in the hope that it will be useful, |
5899 |
06 Dec 11 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
5899 |
06 Dec 11 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5899 |
06 Dec 11 |
nicklas |
GNU General Public License for more details. |
5899 |
06 Dec 11 |
nicklas |
18 |
|
5899 |
06 Dec 11 |
nicklas |
You should have received a copy of the GNU General Public License |
5899 |
06 Dec 11 |
nicklas |
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 |
JEP function that can be used to return the name of a default item in |
5899 |
06 Dec 11 |
nicklas |
a project. The constructor need to specify the project and the type |
5899 |
06 Dec 11 |
nicklas |
of item to look for. Use 'default()' or 'default(col("header"))' in the |
5899 |
06 Dec 11 |
nicklas |
JEP expression to use this function. The first variant will always |
5899 |
06 Dec 11 |
nicklas |
return the default item if one exists for the project. The second |
5899 |
06 Dec 11 |
nicklas |
variant will return the default item only if the 'col("header")' part |
5899 |
06 Dec 11 |
nicklas |
is null or an empty string. |
5899 |
06 Dec 11 |
nicklas |
<p> |
5899 |
06 Dec 11 |
nicklas |
Before this function is used the {@link #setCurrentSubtype(ItemSubtype)} |
5899 |
06 Dec 11 |
nicklas |
can be called to limit the search to items with a specific subtype. If |
5899 |
06 Dec 11 |
nicklas |
there is more than one matching item in a project, it is undefined which |
5899 |
06 Dec 11 |
nicklas |
one is returned, but multiple uses of this function will return the same |
5899 |
06 Dec 11 |
nicklas |
item. |
5899 |
06 Dec 11 |
nicklas |
54 |
|
5899 |
06 Dec 11 |
nicklas |
@author Nicklas |
5899 |
06 Dec 11 |
nicklas |
@since 3.1 |
5899 |
06 Dec 11 |
nicklas |
@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 |
Create a new function instance. |
5899 |
06 Dec 11 |
nicklas |
@param dc The DbControl to use when loading items from the database |
5899 |
06 Dec 11 |
nicklas |
@param project The project (null is allowed) |
5899 |
06 Dec 11 |
nicklas |
@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 |
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 |
@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 |
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 |
// 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 |
// 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 |
// 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 |
Find a default item. If a subtype has been set |
5899 |
06 Dec 11 |
nicklas |
with {@link #setCurrentSubtype(ItemSubtype)} the |
5899 |
06 Dec 11 |
nicklas |
{@link Project#findDefaultItems(DbControl, ItemSubtype, boolean)} |
5899 |
06 Dec 11 |
nicklas |
method is used in non-strict mode, otherwise the |
5899 |
06 Dec 11 |
nicklas |
{@link Project#findDefaultItems(DbControl, Item, boolean)} |
5899 |
06 Dec 11 |
nicklas |
is used in strict mode. |
5899 |
06 Dec 11 |
nicklas |
@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 |
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 |
} |