📄 collectionfunctions.java
字号:
/* * Copyright 2004-2005 Gary Bentley * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.josql.functions;import java.util.List;import java.util.ArrayList;import java.util.Map;import java.util.HashMap;import java.util.TreeMap;import java.util.LinkedHashMap;import java.util.Collections;import com.gentlyweb.utils.Getter;import com.gentlyweb.utils.GeneralComparator;import org.josql.Query;import org.josql.QueryExecutionException;import org.josql.expressions.Expression;import org.josql.internal.Utilities;/** * Defines a set of functions that operate on "collections" of objects in some way. */public class CollectionFunctions extends AbstractFunctionHandler{ private Map foreachQueryCache = null; /** * The id that can be used to get the "CollectionFunctions" handler object from * the Query object. */ public static final String HANDLER_ID = "_internal_collection"; /** * Sort a list according to it's "natural" ordering (see {@link Collections#sort(List)}). * * @param objs The list of objects to sort. * @return The sorted list, according to their natural ordering. */ public List sort (List objs) { Collections.sort (objs); return objs; } /** * Sort a Map by the keys in ascending order (for more optionality in the sort and ordering * see: {@link #sort(Map,String,String)}). * * @param m The map to sort. * @return A List sorted according to the key in ascending order. */ public List sort (Map m) { return this.sort (m, "key", GeneralComparator.ASC); } /** * Sort a Map by it's keys or values in ascending order (for more optionality in the sort and ordering * see: {@link #sort(Map,String,String)}). * * @param m The map to sort. * @param type Should be either: "key" or "value" to indicate which item to sort on. * Use <code>null</code> for key. * @return A List sorted according to the key in ascending order. */ public List sort (Map m, String type) { return this.sort (m, type, GeneralComparator.ASC); } /** * Sort a Map by either it's key or value. * * @param m The map to sort. * @param type Should be either: "key" or "value" to indicate which item to sort on. * Use <code>null</code> for key. * @param dir The direction you want to sort on, either "asc" or "desc". Use <code>null</code> * for "asc". * @return A List sorted according to the key or value. */ public List sort (Map m, String type, String dir) { boolean key = true; String acc = "key"; if ((type != null) && (type.equalsIgnoreCase ("value")) ) { acc = "value"; } String d = GeneralComparator.ASC; if (dir != null) { dir = dir.toUpperCase (); if (dir.equals (GeneralComparator.DESC)) { d = GeneralComparator.DESC; } } GeneralComparator gc = new GeneralComparator (Map.Entry.class); gc.addField (acc, d); List l = new ArrayList (m.entrySet ()); Collections.sort (l, gc); return l; } /** * Get a value from the specified Map. * * @param m The map of objects. * @param exp The expression is evaluated (in the context of the current object) and the * value returned used as the key to the Map, the value it maps to * (which may be null) is returned. * @return The value that the <b>exp</b> value maps to, may be null. */ public Object get (Map m, Expression exp) throws QueryExecutionException { // Evaluate the expression. // Get the current object. return m.get (exp.getValue (this.q.getCurrentObject (), this.q)); } /** * Get a value from the specified List. * * @param l The list of objects. * @param n The index, indices start at 0. * @return The value of the <b>i</b>th element from the list of objects. Return <code>null</code> * if <b>n</b> is out of range. */ public Object get (List l, Number n) { int i = n.intValue (); if ((i > l.size ()) || (i < 0) ) { return null; } return l.get (i); } /** * For each of the objects in the <b>objs</b> List get the value from each one * using the <b>accessor</b> and compare it to the <b>value</b> parameter. The value * param is converted to a string and then to a Boolean value using: {@link Boolean#valueOf(String)}. * * @param objs The list of objects to iterate over. * @param exp The expression to use to get the value from the object in the List. * @param value The value to compare the result of the accessor against. If the parm is <code>null</code> * then it defaults to {@link Boolean#FALSE}. * @return A count of how many times the accessor evaluated to the same value of the * <b>value</b> parm. * @throws QueryExecutionException If the value from the accessor cannot be gained or if * the compare cannot be performed. */ public int count (List objs, Expression exp, Object value) throws QueryExecutionException { Boolean b = Boolean.FALSE; if (value != null) { b = Boolean.valueOf (value.toString ()); } int count = 0; List retVals = new ArrayList (); int size = objs.size (); for (int i = 0; i < size; i++) { Object o = objs.get (i); Object v = null; try { if (Utilities.compare (exp.getValue (o, this.q), b) == 0) { count++; } } catch (Exception e) { throw new QueryExecutionException ("Unable to get value from expression: " + exp + " for item: " + i + " from the list of objects.", e); } } return count; } public int count (Expression exp) throws QueryExecutionException { return this.count ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public int count (List allobjs, Expression exp) throws QueryExecutionException { int count = 0; List retVals = new ArrayList (); int size = allobjs.size (); for (int i = 0; i < size; i++) { Object o = allobjs.get (i); Object v = null; try { if (exp.isTrue (o, this.q)) { count++; } } catch (Exception e) { throw new QueryExecutionException ("Unable to determine whether expression: \"" + exp + "\" is true for object at index: " + i + " from the list of objects.", e); } } return count; } public List toList (List allobjs, Expression exp, String saveValueName) throws QueryExecutionException { return this.collect (allobjs, exp, saveValueName); } public List unique (List objs) { /** Strangely the method below is consistently slower than the method employed! return new ArrayList (new java.util.LinkedHashSet (objs)); */ Map m = new LinkedHashMap (); int s = objs.size (); for (int i = 0; i < s; i++) { m.put (objs.get (i), null); } return new ArrayList (m.keySet ()); } public List unique (Expression exp) throws QueryExecutionException { return this.unique ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME), exp); } public List unique (List objs, Expression exp) throws QueryExecutionException { /** Strangely the method below is consistently slower than the method employed! return new ArrayList (new java.util.LinkedHashSet (objs)); */ Map m = new HashMap (); int s = objs.size (); for (int i = 0; i < s; i++) { Object o = objs.get (i); o = exp.getValue (o, this.q); m.put (o, null); } return new ArrayList (m.keySet ()); } public List collect (List objs, Expression exp, String saveValueName) throws QueryExecutionException { if (saveValueName != null) { Object o = this.q.getSaveValue (saveValueName); if (o != null) { return (List) o; } } List retVals = new ArrayList (); int s = objs.size (); Object co = this.q.getCurrentObject (); for (int i = 0; i < s; i++) { Object o = objs.get (i); this.q.setCurrentObject (o); Object v = null; // Execute the function. try { retVals.add (exp.getValue (o, this.q));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -