📄 defaultgroovymethods.java
字号:
/* * $Id: DefaultGroovyMethods.java,v 1.207 2006/06/27 15:53:35 tug Exp $ * * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved. * * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain copyright statements and * notices. Redistributions must also contain a copy of this document. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name "groovy" must not be used to endorse or promote products * derived from this Software without prior written permission of The Codehaus. * For written permission, please contact info@codehaus.org. * 4. Products derived from this Software may not be called "groovy" nor may * "groovy" appear in their names without prior written permission of The * Codehaus. "groovy" is a registered trademark of The Codehaus. * 5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/ * * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * */package org.codehaus.groovy.runtime;import groovy.lang.*;import groovy.util.CharsetToolkit;import groovy.util.ClosureComparator;import groovy.util.OrderBy;import java.io.*;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.math.BigDecimal;import java.math.BigInteger;import java.net.MalformedURLException;import java.net.ServerSocket;import java.net.Socket;import java.net.URI;import java.net.URISyntaxException;import java.net.URL;import java.security.AccessController;import java.security.PrivilegedAction;import java.util.*;import java.util.logging.Logger;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.codehaus.groovy.tools.RootLoader;/** * This class defines all the new groovy methods which appear on normal JDK * classes inside the Groovy environment. Static methods are used with the * first parameter the destination class. * * @author <a href="mailto:james@coredevelopers.net">James Strachan</a> * @author Jeremy Rayner * @author Sam Pullara * @author Rod Cope * @author Guillaume Laforge * @author John Wilson * @author Hein Meling * @author Dierk Koenig * @author Pilho Kim * @author Marc Guillemot * @version $Revision: 1.207 $ */public class DefaultGroovyMethods { private static Logger log = Logger.getLogger(DefaultGroovyMethods.class.getName()); private static final Integer ONE = new Integer(1); private static final char ZERO_CHAR = '\u0000'; /** * Identity check. Since == is overridden in Groovy with the meaning of equality * we need some fallback to check for object identity. * @param self * @param other * @return true if self and other are identical, false otherwise */ public static boolean is(Object self, Object other){ return self == other; } /** * Allows the closure to be called for the object reference self * * @param self the object to have a closure act upon * @param closure the closure to call on the object * @return result of calling the closure */ public static Object identity(Object self, Closure closure) { closure.setDelegate(self); return closure.call(self); } /** * Allows the subscript operator to be used to lookup dynamic property values. * <code>bean[somePropertyNameExpression]</code>. The normal property notation * of groovy is neater and more concise but only works with compile time known * property names. * * @param self */ public static Object getAt(Object self, String property) { return InvokerHelper.getProperty(self, property); } /** * Allows the subscript operator to be used to set dynamically named property values. * <code>bean[somePropertyNameExpression] = foo</code>. The normal property notation * of groovy is neater and more concise but only works with compile time known * property names. * * @param self */ public static void putAt(Object self, String property, Object newValue) { InvokerHelper.setProperty(self, property, newValue); } /** * Generates a detailed dump string of an object showing its class, * hashCode and fields */ public static String dump(Object self) { if (self == null) { return "null"; } StringBuffer buffer = new StringBuffer("<"); Class klass = self.getClass(); buffer.append(klass.getName()); buffer.append("@"); buffer.append(Integer.toHexString(self.hashCode())); boolean groovyObject = self instanceof GroovyObject; /*jes this may be rewritten to use the new getProperties() stuff * but the original pulls out private variables, whereas getProperties() * does not. What's the real use of dump() here? */ while (klass != null) { Field[] fields = klass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { final Field field = fields[i]; if ((field.getModifiers() & Modifier.STATIC) == 0) { if (groovyObject && field.getName().equals("metaClass")) { continue; } AccessController.doPrivileged(new PrivilegedAction() { public Object run() { field.setAccessible(true); return null; } }); buffer.append(" "); buffer.append(field.getName()); buffer.append("="); try { buffer.append(InvokerHelper.toString(field.get(self))); } catch (Exception e) { buffer.append(e); } } } klass = klass.getSuperclass(); } /* here is a different implementation that uses getProperties(). I have left * it commented out because it returns a slightly different list of properties; * ie it does not return privates. I don't know what dump() really should be doing, * although IMO showing private fields is a no-no */ /* List props = getProperties(self); for(Iterator itr = props.keySet().iterator(); itr.hasNext(); ) { String propName = itr.next().toString(); // the original skipped this, so I will too if(pv.getName().equals("metaClass")) continue; if(pv.getName().equals("class")) continue; buffer.append(" "); buffer.append(propName); buffer.append("="); try { buffer.append(InvokerHelper.toString(props.get(propName))); } catch (Exception e) { buffer.append(e); } } */ buffer.append(">"); return buffer.toString(); } /** * Retrieves the list of {@link MetaProperty} objects for 'self' and wraps it * in a list of {@link PropertyValue} objects that additionally provide * the value for each property of 'self'. * @param self the receiver object * @return list of {@link PropertyValue} objects * @see groovy.util.Expando#getMetaPropertyValues() */ public static List getMetaPropertyValues(Object self) { MetaClass metaClass = InvokerHelper.getMetaClass(self); List mps = metaClass.getProperties(); List props = new ArrayList(mps.size()); for (Iterator itr = mps.iterator(); itr.hasNext();) { MetaProperty mp = (MetaProperty) itr.next(); PropertyValue pv = new PropertyValue(self, mp); props.add(pv); } return props; } /** * Convenience method that calls {@link #getMetaPropertyValues(Object)}(self) * and provides the data in form of simple key/value pairs, i.e. without * type() information. * @param self the receiver object * @return meta properties as Map of key/value pairs */ public static Map getProperties(Object self) { List metaProps = getMetaPropertyValues(self); Map props = new HashMap(metaProps.size()); for (Iterator itr = metaProps.iterator(); itr.hasNext();) { PropertyValue pv = (PropertyValue) itr.next(); try { props.put(pv.getName(), pv.getValue()); } catch (Exception e) { log.throwing(self.getClass().getName(), "getProperty("+pv.getName()+")", e ); } } return props; } /** * Scoped use method */ public static void use(Object self, Class categoryClass, Closure closure) { GroovyCategorySupport.use(categoryClass, closure); } /** * Scoped use method with list of categories */ public static void use(Object self, List categoryClassList, Closure closure) { GroovyCategorySupport.use(categoryClassList, closure); } /** * Print to a console in interactive format */ public static void print(Object self, Object value) { System.out.print(InvokerHelper.toString(value)); } /** * Print a linebreak to the standard out. */ public static void println(Object self) { System.out.println(); } /** * Print to a console in interactive format along with a newline */ public static void println(Object self, Object value) { System.out.println(InvokerHelper.toString(value)); } /** * Printf to a console. Only works with JDK1.5 or later. * * @author Russel Winder * @version 2005.02.01.15.53 */ public static void printf(final Object self, final String format, final Object[] values) { if ( System.getProperty("java.version").charAt(2) == '5' ) { // // Cannot just do: // // System.out.printf(format, values) ; // // because this fails to compile on JDK1.4.x and earlier. So until the entire world is using // JDK1.5 or later then we have to do things by reflection so as to hide the use of printf // from the compiler. In JDK1.5 you might try: // // System.out.getClass().getMethod("printf", String.class, Object[].class).invoke(System.out, format, values) ; // // but of course this doesn't work on JDK1.4 as it relies on varargs. argh. So we are // forced into: // try { System.out.getClass().getMethod("printf", new Class[] {String.class, Object[].class}).invoke(System.out, new Object[] {format, values}) ; } catch ( NoSuchMethodException nsme ) { throw new RuntimeException ("getMethod threw a NoSuchMethodException. This is impossible.") ; } catch ( IllegalAccessException iae ) { throw new RuntimeException ("invoke threw a IllegalAccessException. This is impossible.") ; } catch ( java.lang.reflect.InvocationTargetException ite ) { throw new RuntimeException ("invoke threw a InvocationTargetException. This is impossible.") ; } } else { throw new RuntimeException ("printf requires JDK1.5 or later.") ; } } /** * Returns a formatted string using the specified format string and * arguments. * * <p> * For examples, <pre> * printf ( "Hello, %s!\n" , [ "world" ] as String[] ) * printf ( "Hello, %s!\n" , [ "Groovy" ]) * printf ( "%d + %d = %d\n" , [ 1 , 2 , 1+2 ] as Integer[] ) * printf ( "%d + %d = %d\n" , [ 3 , 3 , 3+3 ]) * * ( 1..5 ).each { printf ( "-- %d\n" , [ it ] as Integer[] ) } * ( 1..5 ).each { printf ( "-- %d\n" , [ it ] as int[] ) } * ( 0x41..0x45 ).each { printf ( "-- %c\n" , [ it ] as char[] ) } * ( 07..011 ).each { printf ( "-- %d\n" , [ it ] as byte[] ) } * ( 7..11 ).each { printf ( "-- %d\n" , [ it ] as short[] ) } * ( 7..11 ).each { printf ( "-- %d\n" , [ it ] as long[] ) } * ( 7..11 ).each { printf ( "-- %5.2f\n" , [ it ] as float[] ) } * ( 7..11 ).each { printf ( "-- %5.2g\n" , [ it ] as double[] ) } * </pre> * <p> * * @param format * A format string * * @param arg * Argument which is referenced by the format specifiers in the format * string. The type of <code>arg</code> should be one of Object[], List, * int[], short[], byte[], char[], boolean[], long[], float[], or double[]. * * @since JDK 1.5 * * @author Pilho Kim * @version 2005.07.25.02.31 */ public static void printf(final Object self, final String format, Object arg) { if (arg instanceof Object[]) { printf(self, format, (Object[]) arg); return; } else if (arg instanceof List) { printf(self, format, ((List) arg).toArray()); return; } else if (!arg.getClass().isArray()) { Object[] o = (Object[]) java.lang.reflect.Array.newInstance(arg.getClass(), 1); o[0]=arg; printf(self, format, o); return; } Object[] ans = null; String elemType = arg.getClass().getName(); if (elemType.equals("[I")) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -