private static <T> T callClosureForNode(Closure<T> closure, Object node, int level) { if (closure.getMaximumNumberOfParameters() == 2) { return closure.call(node, level); } return closure.call(node); }
protected static <T, K, V> T callClosureForMapEntryAndCounter(@ClosureParams(value=FromString.class, options={"K,V,Integer", "K,V","Map.Entry<K,V>"}) Closure<T> closure, Map.Entry<K,V> entry, int counter) { if (closure.getMaximumNumberOfParameters() == 3) { return closure.call(entry.getKey(), entry.getValue(), counter); } if (closure.getMaximumNumberOfParameters() == 2) { return closure.call(entry, counter); } return closure.call(entry); }
protected static <T> T callClosureForLine(@ClosureParams(value=FromString.class, options={"String","String,Integer"}) Closure<T> closure, String line, int counter) { if (closure.getMaximumNumberOfParameters() == 2) { return closure.call(line, counter); } return closure.call(line); }
/** * Does the Closure have a single String argument. * @param c a Closure * @return true if it has exactly one argument and the type is String */ public static boolean hasSingleStringArg(Closure c) { if (c.getMaximumNumberOfParameters() != 1) return false; String typeName = c.getParameterTypes()[0].getName(); return typeName.equals("java.lang.String"); }
protected static <T, K, V> T callClosureForMapEntry(@ClosureParams(value=FromString.class, options={"K,V","Map.Entry<K,V>"}) Closure<T> closure, Map.Entry<K,V> entry) { if (closure.getMaximumNumberOfParameters() == 2) { return closure.call(entry.getKey(), entry.getValue()); } return closure.call(entry); }
public BooleanClosureWrapper(Closure wrapped) { this.wrapped = wrapped; this.bmi = new BooleanReturningMethodInvoker("call"); numberOfArguments = wrapped.getMaximumNumberOfParameters(); }
/** * Does the Closure have a single char-like (char or Character) argument. * @param c a Closure * @return true if it has exactly one argument and the type is char or Character */ public static boolean hasSingleCharacterArg(Closure c) { if (c.getMaximumNumberOfParameters() != 1) return false; String typeName = c.getParameterTypes()[0].getName(); return typeName.equals("char") || typeName.equals("java.lang.Character"); }
public void handleNotification(Notification notification, Object handback) { AttributeChangeNotification note = (AttributeChangeNotification) notification; Map event = (Map) handback; if (event != null) { Object del = event.get("managedObject"); Object callback = event.get("callback"); if (callback != null && callback instanceof Closure) { Closure closure = (Closure) callback; closure.setDelegate(del); if (closure.getMaximumNumberOfParameters() == 1) closure.call(buildAttributeNotificationPacket(note)); else closure.call(); } } }
/** * This is the implemented method for NotificationListener. It is called by an event emitter to dispatch * JMX events to listeners. Here it handles internal JmxBuilder events. * * @param notification the notification object passed to closure used to handle JmxBuilder events. * @param handback - In this case, the handback is the closure to execute when the event is handled. */ public void handleNotification(Notification notification, Object handback) { Map event = (Map) handback; if (event != null) { Object del = event.get("managedObject"); Object callback = event.get("callback"); if (callback != null && callback instanceof Closure) { Closure closure = (Closure) callback; closure.setDelegate(del); if (closure.getMaximumNumberOfParameters() == 1) closure.call(buildOperationNotificationPacket(notification)); else closure.call(); } } }
/** * Write or read+write flow file contents through streams. * * @param c Closure that could receive one parameter OutputStream to perform write, * or two parameters InputStream and OutputStream to perform read and write. * @return reference to self */ public GroovySessionFile write(Closure c) { if (c.getMaximumNumberOfParameters() == 1) { this.write(new OutputStreamCallback() { public void process(OutputStream out) throws IOException { c.call(out); } }); } else { this.write(new StreamCallback() { public void process(InputStream in, OutputStream out) throws IOException { c.call(in, out); } }); } return this; }
public ComposedClosure(Closure first, Closure<V> second) { super(first.clone()); this.first = (Closure) getOwner(); this.second = (Closure<V>) second.clone(); maximumNumberOfParameters = first.getMaximumNumberOfParameters(); }
MemoizeFunction(final MemoizeCache<Object, ?> cache, Closure<V> closure) { super(closure.getOwner()); this.cache = coerce(cache); this.closure = closure; parameterTypes = closure.getParameterTypes(); maximumNumberOfParameters = closure.getMaximumNumberOfParameters(); }
@Override public Writer writeTo(Writer out) throws IOException { String[] s = getStrings(); int numberOfValues = values.length; for (int i = 0, size = s.length; i < size; i++) { out.write(s[i]); if (i < numberOfValues) { final Object value = values[i]; if (value instanceof Closure) { final Closure c = (Closure) value; int maximumNumberOfParameters = c.getMaximumNumberOfParameters(); if (maximumNumberOfParameters == 0) { InvokerHelper.write(out, c.call()); } else if (maximumNumberOfParameters == 1) { c.call(out); } else { throw new GroovyRuntimeException("Trying to evaluate a GString containing a Closure taking " + maximumNumberOfParameters + " parameters"); } } else { InvokerHelper.write(out, value); } } } return out; }
/** * Sorts the elements from this array into a newly created array using * the Closure to determine the correct ordering. * <p> * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare * its two parameters for order, returning a negative integer, zero, or a positive integer when the * first parameter is less than, equal to, or greater than the second respectively. Otherwise, * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer) * which is then used for further comparison. * * @param self the array containing the elements to be sorted * @param condition a Closure used to determine the correct ordering * @return a sorted array * @see #toSorted(Object[], Comparator) * @since 2.4.0 */ public static <T> T[] toSorted(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure condition) { Comparator<T> comparator = (condition.getMaximumNumberOfParameters() == 1) ? new OrderBy<T>(condition) : new ClosureComparator<T>(condition); return toSorted(self, comparator); }
/** * Sorts the given iterator items into a sorted iterator using the Closure to determine the correct ordering. * The original iterator will be fully processed after the method call. * <p> * If the closure has two parameters it is used like a traditional Comparator. * I.e. it should compare its two parameters for order, returning a negative integer, * zero, or a positive integer when the first parameter is less than, equal to, * or greater than the second respectively. Otherwise, the Closure is assumed * to take a single parameter and return a Comparable (typically an Integer) * which is then used for further comparison. * * @param self the Iterator to be sorted * @param closure a Closure used to determine the correct ordering * @return the sorted items as an Iterator * @see #toSorted(Iterator, Comparator) * @since 2.4.0 */ public static <T> Iterator<T> toSorted(Iterator<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) { Comparator<T> comparator = (closure.getMaximumNumberOfParameters() == 1) ? new OrderBy<T>(closure) : new ClosureComparator<T>(closure); return toSorted(self, comparator); }
/** * Sorts the elements from the given map into a new ordered map using * the supplied Closure condition as a comparator to determine the ordering. The original map is unchanged. * <p> * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare * its two entry parameters for order, returning a negative integer, zero, or a positive integer when the * first parameter is less than, equal to, or greater than the second respectively. Otherwise, * the Closure is assumed to take a single entry parameter and return a Comparable (typically an Integer) * which is then used for further comparison. * <pre class="groovyTestCase"> * def map = [a:5, b:3, c:6, d:4].toSorted { a, b -> a.value <=> b.value } * assert map.toString() == '[b:3, d:4, a:5, c:6]' * </pre> * * @param self the original unsorted map * @param condition a Closure used as a comparator * @return the sorted map * @since 2.4.0 */ public static <K, V> Map<K, V> toSorted(Map<K, V> self, @ClosureParams(value=FromString.class, options={"Map.Entry<K,V>","Map.Entry<K,V>,Map.Entry<K,V>"}) Closure condition) { Comparator<Map.Entry<K,V>> comparator = (condition.getMaximumNumberOfParameters() == 1) ? new OrderBy<Map.Entry<K,V>>(condition) : new ClosureComparator<Map.Entry<K,V>>(condition); return toSorted(self, comparator); }
/** * Returns a new Array containing the items from the original Array but with duplicates removed with the supplied * comparator determining which items are unique. * <p> * <pre class="groovyTestCase"> * String[] letters = ['c', 'a', 't', 's', 'A', 't', 'h', 'a', 'T'] * String[] expected = ['c', 'a', 't', 's', 'h'] * assert letters.toUnique{ p1, p2 -> p1.toLowerCase() <=> p2.toLowerCase() } == expected * assert letters.toUnique{ it.toLowerCase() } == expected * </pre> * * @param self an array * @param condition a Closure used to determine unique items * @return the unique items from the array */ @SuppressWarnings("unchecked") public static <T> T[] toUnique(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure condition) { Comparator<T> comparator = condition.getMaximumNumberOfParameters() == 1 ? new OrderBy<T>(condition, true) : new ClosureComparator<T>(condition); return toUnique(self, comparator); }
/** * Returns an iterator equivalent to this iterator but with all duplicated items * removed by using a Closure to determine duplicate (equal) items. * The original iterator will be fully processed after the call. * <p> * If the closure takes a single parameter, the argument passed will be each element, * and the closure should return a value used for comparison (either using * {@link java.lang.Comparable#compareTo(java.lang.Object)} or {@link java.lang.Object#equals(java.lang.Object)}). * If the closure takes two parameters, two items from the Iterator * will be passed as arguments, and the closure should return an * int value (with 0 indicating the items are not unique). * * @param self an Iterator * @param condition a Closure used to determine unique items * @return the modified Iterator * @since 1.5.5 */ public static <T> Iterator<T> unique(Iterator<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure condition) { Comparator<T> comparator = condition.getMaximumNumberOfParameters() == 1 ? new OrderBy<T>(condition, true) : new ClosureComparator<T>(condition); return unique(self, comparator); }
/** * Sorts this Iterable using the given Closure to determine the correct ordering. The elements are first placed * into a new list which is then sorted and returned - leaving the original Iterable unchanged. * <p> * If the Closure has two parameters * it is used like a traditional Comparator. I.e. it should compare * its two parameters for order, returning a negative integer, * zero, or a positive integer when the first parameter is less than, * equal to, or greater than the second respectively. Otherwise, * the Closure is assumed to take a single parameter and return a * Comparable (typically an Integer) which is then used for * further comparison. * <pre class="groovyTestCase">assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { it.length() }</pre> * <pre class="groovyTestCase">assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { a, b -> a.length() <=> b.length() }</pre> * * @param self the Iterable to be sorted * @param closure a 1 or 2 arg Closure used to determine the correct ordering * @return a newly created sorted List * @see #toSorted(Iterable, Comparator) * @since 2.4.0 */ public static <T> List<T> toSorted(Iterable<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) { Comparator<T> comparator = (closure.getMaximumNumberOfParameters() == 1) ? new OrderBy<T>(closure) : new ClosureComparator<T>(closure); return toSorted(self, comparator); }
/** * Returns an iterator equivalent to this iterator but with all duplicated items * removed where duplicate (equal) items are deduced by calling the supplied Closure condition. * <p> * If the supplied Closure takes a single parameter, the argument passed will be each element, * and the closure should return a value used for comparison (either using * {@link java.lang.Comparable#compareTo(java.lang.Object)} or {@link java.lang.Object#equals(java.lang.Object)}). * If the closure takes two parameters, two items from the Iterator * will be passed as arguments, and the closure should return an * int value (with 0 indicating the items are not unique). * <pre class="groovyTestCase"> * def items = "Hello".toList() + [null, null] + "there".toList() * def toLower = { it == null ? null : it.toLowerCase() } * def noDups = items.iterator().toUnique(toLower).toList() * assert noDups == ['H', 'e', 'l', 'o', null, 't', 'r'] * </pre> * <pre class="groovyTestCase">assert [1,4] == [1,3,4,5].toUnique { it % 2 }</pre> * <pre class="groovyTestCase">assert [2,3,4] == [2,3,3,4].toUnique { a, b -> a <=> b }</pre> * * @param self an Iterator * @param condition a Closure used to determine unique items * @return an Iterator with no duplicate items * @since 2.4.0 */ public static <T> Iterator<T> toUnique(Iterator<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure condition) { return toUnique(self, condition.getMaximumNumberOfParameters() == 1 ? new OrderBy<T>(condition, true) : new ClosureComparator<T>(condition)); }