Source Code Cross Referenced for Objects.java in  » J2EE » wicket » org » apache » wicket » util » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » wicket » org.apache.wicket.util.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.wicket.util.lang;
0018:
0019:        import java.io.ByteArrayInputStream;
0020:        import java.io.ByteArrayOutputStream;
0021:        import java.io.IOException;
0022:        import java.io.InputStream;
0023:        import java.io.ObjectInputStream;
0024:        import java.io.ObjectOutputStream;
0025:        import java.io.ObjectStreamClass;
0026:        import java.io.OutputStream;
0027:        import java.lang.reflect.Array;
0028:        import java.math.BigDecimal;
0029:        import java.math.BigInteger;
0030:        import java.util.HashMap;
0031:
0032:        import org.apache.wicket.Application;
0033:        import org.apache.wicket.Component;
0034:        import org.apache.wicket.WicketRuntimeException;
0035:        import org.apache.wicket.application.IClassResolver;
0036:        import org.apache.wicket.settings.IApplicationSettings;
0037:        import org.apache.wicket.util.io.ByteCountingOutputStream;
0038:        import org.apache.wicket.util.io.IObjectStreamFactory;
0039:        import org.apache.wicket.util.io.IObjectStreamFactory.DefaultObjectStreamFactory;
0040:        import org.apache.wicket.util.string.Strings;
0041:        import org.slf4j.Logger;
0042:        import org.slf4j.LoggerFactory;
0043:
0044:        /**
0045:         * Object utilities.
0046:         * 
0047:         * @author Jonathan Locke
0048:         */
0049:        public final class Objects {
0050:            /**
0051:             * Interface that enables users to plugin the way object sizes are
0052:             * calculated with Wicket.
0053:             */
0054:            public static interface IObjectSizeOfStrategy {
0055:                /**
0056:                 * Computes the size of an object. This typically is an estimation, not
0057:                 * an absolute accurate size.
0058:                 * 
0059:                 * @param object
0060:                 *            Object to compute size of
0061:                 * @return The size of the object in bytes.
0062:                 */
0063:                long sizeOf(Object object);
0064:            }
0065:
0066:            /**
0067:             * {@link IObjectSizeOfStrategy} that works by serializing the object to an
0068:             * instance of {@link ByteCountingOutputStream}, which records the number
0069:             * of bytes written to it. Hence, this gives the size of the object as it
0070:             * would be serialized,including all the overhead of writing class headers
0071:             * etc. Not very accurate (the real memory consumption should be lower) but
0072:             * the best we can do in a cheap way pre JDK 5.
0073:             */
0074:            public static final class SerializingObjectSizeOfStrategy implements 
0075:                    IObjectSizeOfStrategy {
0076:                /**
0077:                 * @see org.apache.wicket.util.lang.Objects.IObjectSizeOfStrategy#sizeOf(java.lang.Object)
0078:                 */
0079:                public long sizeOf(Object object) {
0080:                    if (object == null) {
0081:                        return 0;
0082:                    }
0083:                    try {
0084:                        final ByteCountingOutputStream out = new ByteCountingOutputStream();
0085:                        new ObjectOutputStream(out).writeObject(object);
0086:                        out.close();
0087:                        return out.size();
0088:                    } catch (IOException e) {
0089:                        return -1;
0090:                    }
0091:                }
0092:
0093:            }
0094:
0095:            private static final class ReplaceObjectInputStream extends
0096:                    ObjectInputStream {
0097:                private final ClassLoader classloader;
0098:                private final HashMap replacedComponents;
0099:
0100:                private ReplaceObjectInputStream(InputStream in,
0101:                        HashMap replacedComponents, ClassLoader classloader)
0102:                        throws IOException {
0103:                    super (in);
0104:                    this .replacedComponents = replacedComponents;
0105:                    this .classloader = classloader;
0106:                    enableResolveObject(true);
0107:                }
0108:
0109:                // This overide is required to resolve classess inside in different
0110:                // bundle, i.e.
0111:                // The classess can be resolved by OSGI classresolver implementation
0112:                protected Class resolveClass(ObjectStreamClass desc)
0113:                        throws IOException, ClassNotFoundException {
0114:                    String className = desc.getName();
0115:
0116:                    try {
0117:                        return Class.forName(className, true, classloader);
0118:                    } catch (ClassNotFoundException ex1) {
0119:                        // ignore this exception.
0120:                        log
0121:                                .debug("Class not found by using objects own classloader, trying the IClassResolver");
0122:                    }
0123:
0124:                    Application application = Application.get();
0125:                    IApplicationSettings applicationSettings = application
0126:                            .getApplicationSettings();
0127:                    IClassResolver classResolver = applicationSettings
0128:                            .getClassResolver();
0129:
0130:                    Class candidate = null;
0131:                    try {
0132:                        candidate = classResolver.resolveClass(className);
0133:                        if (candidate == null) {
0134:                            candidate = super .resolveClass(desc);
0135:                        }
0136:                    } catch (WicketRuntimeException ex) {
0137:                        if (ex.getCause() instanceof  ClassNotFoundException) {
0138:                            throw (ClassNotFoundException) ex.getCause();
0139:                        }
0140:                    }
0141:                    return candidate;
0142:                }
0143:
0144:                protected Object resolveObject(Object obj) throws IOException {
0145:                    Object replaced = replacedComponents.get(obj);
0146:                    if (replaced != null) {
0147:                        return replaced;
0148:                    }
0149:                    return super .resolveObject(obj);
0150:                }
0151:            }
0152:
0153:            private static final class ReplaceObjectOutputStream extends
0154:                    ObjectOutputStream {
0155:                private final HashMap replacedComponents;
0156:
0157:                private ReplaceObjectOutputStream(OutputStream out,
0158:                        HashMap replacedComponents) throws IOException {
0159:                    super (out);
0160:                    this .replacedComponents = replacedComponents;
0161:                    enableReplaceObject(true);
0162:                }
0163:
0164:                protected Object replaceObject(Object obj) throws IOException {
0165:                    if (obj instanceof  Component) {
0166:                        String name = ((Component) obj).getPath();
0167:                        replacedComponents.put(name, obj);
0168:                        return name;
0169:                    }
0170:                    return super .replaceObject(obj);
0171:                }
0172:            }
0173:
0174:            /** Type tag meaning java.math.BigDecimal. */
0175:            private static final int BIGDEC = 9;
0176:
0177:            /** Type tag meaning java.math.BigInteger. */
0178:            private static final int BIGINT = 6;
0179:
0180:            /** Type tag meaning boolean. */
0181:            private static final int BOOL = 0;
0182:
0183:            /** Type tag meaning byte. */
0184:            private static final int BYTE = 1;
0185:
0186:            /** Type tag meaning char. */
0187:            private static final int CHAR = 2;
0188:
0189:            /** Type tag meaning double. */
0190:            private static final int DOUBLE = 8;
0191:
0192:            /** Type tag meaning float. */
0193:            private static final int FLOAT = 7;
0194:
0195:            /** Type tag meaning int. */
0196:            private static final int INT = 4;
0197:
0198:            /** log. */
0199:            private static final Logger log = LoggerFactory
0200:                    .getLogger(Objects.class);
0201:
0202:            /** Type tag meaning long. */
0203:            private static final int LONG = 5;
0204:
0205:            /**
0206:             * The smallest type tag that represents reals as opposed to integers. You
0207:             * can see whether a type tag represents reals or integers by comparing the
0208:             * tag to this constant: all tags less than this constant represent
0209:             * integers, and all tags greater than or equal to this constant represent
0210:             * reals. Of course, you must also check for NONNUMERIC, which means it is
0211:             * not a number at all.
0212:             */
0213:            private static final int MIN_REAL_TYPE = FLOAT;
0214:
0215:            /** Type tag meaning something other than a number. */
0216:            private static final int NONNUMERIC = 10;
0217:
0218:            /** Type tag meaning short. */
0219:            private static final int SHORT = 3;
0220:
0221:            /** defaults for primitives. */
0222:            private static final HashMap primitiveDefaults = new HashMap();
0223:
0224:            /**
0225:             * The default object stream factory to use. Keep this as a static here
0226:             * opposed to in Application, as the Application most likely isn't available
0227:             * in the threads we'll be using this with.
0228:             */
0229:            private static IObjectStreamFactory objectStreamFactory = new IObjectStreamFactory.DefaultObjectStreamFactory();
0230:
0231:            /**
0232:             * Strategy for calculating sizes of objects. Note: I didn't make this an
0233:             * application setting as we have enough of those already, and the typical
0234:             * way this probably would be used is that install a different one according
0235:             * to the JDK version used, so varying them between applications doesn't
0236:             * make a lot of sense.
0237:             */
0238:            private static IObjectSizeOfStrategy objectSizeOfStrategy = new SerializingObjectSizeOfStrategy();
0239:
0240:            static {
0241:                primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
0242:                primitiveDefaults.put(Byte.TYPE, new Byte((byte) 0));
0243:                primitiveDefaults.put(Short.TYPE, new Short((short) 0));
0244:                primitiveDefaults.put(Character.TYPE, new Character((char) 0));
0245:                primitiveDefaults.put(Integer.TYPE, new Integer(0));
0246:                primitiveDefaults.put(Long.TYPE, new Long(0L));
0247:                primitiveDefaults.put(Float.TYPE, new Float(0.0f));
0248:                primitiveDefaults.put(Double.TYPE, new Double(0.0));
0249:                primitiveDefaults.put(BigInteger.class, new BigInteger("0"));
0250:                primitiveDefaults.put(BigDecimal.class, new BigDecimal(0.0));
0251:            }
0252:
0253:            /**
0254:             * Evaluates the given object as a BigDecimal.
0255:             * 
0256:             * @param value
0257:             *            an object to interpret as a BigDecimal
0258:             * @return the BigDecimal value implied by the given object
0259:             * @throws NumberFormatException
0260:             *             if the given object can't be understood as a BigDecimal
0261:             */
0262:            public static BigDecimal bigDecValue(Object value)
0263:                    throws NumberFormatException {
0264:                if (value == null) {
0265:                    return BigDecimal.valueOf(0L);
0266:                }
0267:                Class c = value.getClass();
0268:                if (c == BigDecimal.class) {
0269:                    return (BigDecimal) value;
0270:                }
0271:                if (c == BigInteger.class) {
0272:                    return new BigDecimal((BigInteger) value);
0273:                }
0274:                if (c.getSuperclass() == Number.class) {
0275:                    return new BigDecimal(((Number) value).doubleValue());
0276:                }
0277:                if (c == Boolean.class) {
0278:                    return BigDecimal
0279:                            .valueOf(((Boolean) value).booleanValue() ? 1 : 0);
0280:                }
0281:                if (c == Character.class) {
0282:                    return BigDecimal.valueOf(((Character) value).charValue());
0283:                }
0284:                return new BigDecimal(stringValue(value, true));
0285:            }
0286:
0287:            /**
0288:             * Evaluates the given object as a BigInteger.
0289:             * 
0290:             * @param value
0291:             *            an object to interpret as a BigInteger
0292:             * @return the BigInteger value implied by the given object
0293:             * @throws NumberFormatException
0294:             *             if the given object can't be understood as a BigInteger
0295:             */
0296:            public static BigInteger bigIntValue(Object value)
0297:                    throws NumberFormatException {
0298:                if (value == null) {
0299:                    return BigInteger.valueOf(0L);
0300:                }
0301:                Class c = value.getClass();
0302:                if (c == BigInteger.class) {
0303:                    return (BigInteger) value;
0304:                }
0305:                if (c == BigDecimal.class) {
0306:                    return ((BigDecimal) value).toBigInteger();
0307:                }
0308:                if (c.getSuperclass() == Number.class) {
0309:                    return BigInteger.valueOf(((Number) value).longValue());
0310:                }
0311:                if (c == Boolean.class) {
0312:                    return BigInteger
0313:                            .valueOf(((Boolean) value).booleanValue() ? 1 : 0);
0314:                }
0315:                if (c == Character.class) {
0316:                    return BigInteger.valueOf(((Character) value).charValue());
0317:                }
0318:                return new BigInteger(stringValue(value, true));
0319:            }
0320:
0321:            /**
0322:             * Evaluates the given object as a boolean: if it is a Boolean object, it's
0323:             * easy; if it's a Number or a Character, returns true for non-zero objects;
0324:             * and otherwise returns true for non-null objects.
0325:             * 
0326:             * @param value
0327:             *            an object to interpret as a boolean
0328:             * @return the boolean value implied by the given object
0329:             */
0330:            public static boolean booleanValue(Object value) {
0331:                if (value == null) {
0332:                    return false;
0333:                }
0334:                Class c = value.getClass();
0335:                if (c == Boolean.class) {
0336:                    return ((Boolean) value).booleanValue();
0337:                }
0338:                if (c == Character.class) {
0339:                    return ((Character) value).charValue() != 0;
0340:                }
0341:                if (value instanceof  Number) {
0342:                    return ((Number) value).doubleValue() != 0;
0343:                }
0344:                return true; // non-null
0345:            }
0346:
0347:            /**
0348:             * De-serializes an object from a byte array.
0349:             * 
0350:             * @param data
0351:             *            The serialized object
0352:             * @return The object
0353:             */
0354:            public static Object byteArrayToObject(final byte[] data) {
0355:                try {
0356:                    final ByteArrayInputStream in = new ByteArrayInputStream(
0357:                            data);
0358:                    try {
0359:                        return objectStreamFactory.newObjectInputStream(in)
0360:                                .readObject();
0361:                    } finally {
0362:                        in.close();
0363:                    }
0364:                } catch (ClassNotFoundException e) {
0365:                    throw new RuntimeException(
0366:                            "Could not deserialize object using `"
0367:                                    + objectStreamFactory.getClass().getName()
0368:                                    + "` object factory", e);
0369:                } catch (IOException e) {
0370:                    throw new RuntimeException(
0371:                            "Could not deserialize object using `"
0372:                                    + objectStreamFactory.getClass().getName()
0373:                                    + "` object factory", e);
0374:                }
0375:            }
0376:
0377:            /**
0378:             * Makes a deep clone of an object by serializing and deserializing it. The
0379:             * object must be fully serializable to be cloned. This method will not
0380:             * clone wicket Components, it will just reuse those instances so that the
0381:             * complete component tree is not copied over only the model data.
0382:             * 
0383:             * @param object
0384:             *            The object to clone
0385:             * @return A deep copy of the object
0386:             */
0387:            public static Object cloneModel(final Object object) {
0388:                if (object == null) {
0389:                    return null;
0390:                } else {
0391:                    try {
0392:                        final ByteArrayOutputStream out = new ByteArrayOutputStream(
0393:                                256);
0394:                        final HashMap replacedObjects = new HashMap();
0395:                        ObjectOutputStream oos = new ReplaceObjectOutputStream(
0396:                                out, replacedObjects);
0397:                        oos.writeObject(object);
0398:                        ObjectInputStream ois = new ReplaceObjectInputStream(
0399:                                new ByteArrayInputStream(out.toByteArray()),
0400:                                replacedObjects, object.getClass()
0401:                                        .getClassLoader());
0402:                        return ois.readObject();
0403:                    } catch (ClassNotFoundException e) {
0404:                        throw new WicketRuntimeException(
0405:                                "Internal error cloning object", e);
0406:                    } catch (IOException e) {
0407:                        throw new WicketRuntimeException(
0408:                                "Internal error cloning object", e);
0409:                    }
0410:                }
0411:            }
0412:
0413:            /**
0414:             * Makes a deep clone of an object by serializing and deserializing it. The
0415:             * object must be fully serializable to be cloned. No extra debug info is
0416:             * gathered.
0417:             * 
0418:             * @param object
0419:             *            The object to clone
0420:             * @return A deep copy of the object
0421:             * @see #cloneObject(Object, boolean)
0422:             */
0423:            public static Object cloneObject(final Object object) {
0424:                if (object == null) {
0425:                    return null;
0426:                } else {
0427:                    try {
0428:                        final ByteArrayOutputStream out = new ByteArrayOutputStream(
0429:                                256);
0430:                        ObjectOutputStream oos = new ObjectOutputStream(out);
0431:                        oos.writeObject(object);
0432:                        ObjectInputStream ois = new ObjectInputStream(
0433:                                new ByteArrayInputStream(out.toByteArray())) {
0434:                            // This overide is required to resolve classess inside in
0435:                            // different
0436:                            // bundle, i.e.
0437:                            // The classess can be resolved by OSGI classresolver
0438:                            // implementation
0439:                            protected Class resolveClass(ObjectStreamClass desc)
0440:                                    throws IOException, ClassNotFoundException {
0441:                                String className = desc.getName();
0442:
0443:                                try {
0444:                                    return Class.forName(className, true,
0445:                                            object.getClass().getClassLoader());
0446:                                } catch (ClassNotFoundException ex1) {
0447:                                    // ignore this exception.
0448:                                    log
0449:                                            .debug("Class not found by using objects own classloader, trying the IClassResolver");
0450:                                }
0451:
0452:                                Application application = Application.get();
0453:                                IApplicationSettings applicationSettings = application
0454:                                        .getApplicationSettings();
0455:                                IClassResolver classResolver = applicationSettings
0456:                                        .getClassResolver();
0457:
0458:                                Class candidate = null;
0459:                                try {
0460:                                    candidate = classResolver
0461:                                            .resolveClass(className);
0462:                                    if (candidate == null) {
0463:                                        candidate = super .resolveClass(desc);
0464:                                    }
0465:                                } catch (WicketRuntimeException ex) {
0466:                                    if (ex.getCause() instanceof  ClassNotFoundException) {
0467:                                        throw (ClassNotFoundException) ex
0468:                                                .getCause();
0469:                                    }
0470:                                }
0471:                                return candidate;
0472:                            }
0473:                        };
0474:                        return ois.readObject();
0475:                    } catch (ClassNotFoundException e) {
0476:                        throw new WicketRuntimeException(
0477:                                "Internal error cloning object", e);
0478:                    } catch (IOException e) {
0479:                        throw new WicketRuntimeException(
0480:                                "Internal error cloning object", e);
0481:                    }
0482:                }
0483:            }
0484:
0485:            /**
0486:             * Compares two objects for equality, even if it has to convert one of them
0487:             * to the other type. If both objects are numeric they are converted to the
0488:             * widest type and compared. If one is non-numeric and one is numeric the
0489:             * non-numeric is converted to double and compared to the double numeric
0490:             * value. If both are non-numeric and Comparable and the types are
0491:             * compatible (i.e. v1 is of the same or superclass of v2's type) they are
0492:             * compared with Comparable.compareTo(). If both values are non-numeric and
0493:             * not Comparable or of incompatible classes this will throw and
0494:             * IllegalArgumentException.
0495:             * 
0496:             * @param v1
0497:             *            First value to compare
0498:             * @param v2
0499:             *            second value to compare
0500:             * 
0501:             * @return integer describing the comparison between the two objects. A
0502:             *         negative number indicates that v1 < v2. Positive indicates that
0503:             *         v1 > v2. Zero indicates v1 == v2.
0504:             * 
0505:             * @throws IllegalArgumentException
0506:             *             if the objects are both non-numeric yet of incompatible types
0507:             *             or do not implement Comparable.
0508:             */
0509:            public static int compareWithConversion(Object v1, Object v2) {
0510:                int result;
0511:
0512:                if (v1 == v2) {
0513:                    result = 0;
0514:                } else {
0515:                    int t1 = getNumericType(v1), t2 = getNumericType(v2), type = getNumericType(
0516:                            t1, t2, true);
0517:
0518:                    switch (type) {
0519:                    case BIGINT:
0520:                        result = bigIntValue(v1).compareTo(bigIntValue(v2));
0521:                        break;
0522:
0523:                    case BIGDEC:
0524:                        result = bigDecValue(v1).compareTo(bigDecValue(v2));
0525:                        break;
0526:
0527:                    case NONNUMERIC:
0528:                        if ((t1 == NONNUMERIC) && (t2 == NONNUMERIC)) {
0529:                            if ((v1 instanceof  Comparable)
0530:                                    && v1.getClass().isAssignableFrom(
0531:                                            v2.getClass())) {
0532:                                result = ((Comparable) v1).compareTo(v2);
0533:                                break;
0534:                            } else {
0535:                                throw new IllegalArgumentException(
0536:                                        "invalid comparison: "
0537:                                                + v1.getClass().getName()
0538:                                                + " and "
0539:                                                + v2.getClass().getName());
0540:                            }
0541:                        }
0542:                        // else fall through
0543:                    case FLOAT:
0544:                    case DOUBLE:
0545:                        double dv1 = doubleValue(v1),
0546:                        dv2 = doubleValue(v2);
0547:
0548:                        return (dv1 == dv2) ? 0 : ((dv1 < dv2) ? -1 : 1);
0549:
0550:                    default:
0551:                        long lv1 = longValue(v1),
0552:                        lv2 = longValue(v2);
0553:
0554:                        return (lv1 == lv2) ? 0 : ((lv1 < lv2) ? -1 : 1);
0555:                    }
0556:                }
0557:                return result;
0558:            }
0559:
0560:            /**
0561:             * Returns the value converted numerically to the given class type
0562:             * 
0563:             * This method also detects when arrays are being converted and converts the
0564:             * components of one array to the type of the other.
0565:             * 
0566:             * @param value
0567:             *            an object to be converted to the given type
0568:             * @param toType
0569:             *            class type to be converted to
0570:             * @return converted value of the type given, or value if the value cannot
0571:             *         be converted to the given type.
0572:             */
0573:            public static Object convertValue(Object value, Class toType) {
0574:                Object result = null;
0575:
0576:                if (value != null) {
0577:                    /* If array -> array then convert components of array individually */
0578:                    if (value.getClass().isArray() && toType.isArray()) {
0579:                        Class componentType = toType.getComponentType();
0580:
0581:                        result = Array.newInstance(componentType, Array
0582:                                .getLength(value));
0583:                        for (int i = 0, icount = Array.getLength(value); i < icount; i++) {
0584:                            Array.set(result, i, convertValue(Array.get(value,
0585:                                    i), componentType));
0586:                        }
0587:                    } else {
0588:                        if ((toType == Integer.class)
0589:                                || (toType == Integer.TYPE)) {
0590:                            result = new Integer((int) longValue(value));
0591:                        }
0592:                        if ((toType == Double.class) || (toType == Double.TYPE)) {
0593:                            result = new Double(doubleValue(value));
0594:                        }
0595:                        if ((toType == Boolean.class)
0596:                                || (toType == Boolean.TYPE)) {
0597:                            result = booleanValue(value) ? Boolean.TRUE
0598:                                    : Boolean.FALSE;
0599:                        }
0600:                        if ((toType == Byte.class) || (toType == Byte.TYPE)) {
0601:                            result = new Byte((byte) longValue(value));
0602:                        }
0603:                        if ((toType == Character.class)
0604:                                || (toType == Character.TYPE)) {
0605:                            result = new Character((char) longValue(value));
0606:                        }
0607:                        if ((toType == Short.class) || (toType == Short.TYPE)) {
0608:                            result = new Short((short) longValue(value));
0609:                        }
0610:                        if ((toType == Long.class) || (toType == Long.TYPE)) {
0611:                            result = new Long(longValue(value));
0612:                        }
0613:                        if ((toType == Float.class) || (toType == Float.TYPE)) {
0614:                            result = new Float(doubleValue(value));
0615:                        }
0616:                        if (toType == BigInteger.class) {
0617:                            result = bigIntValue(value);
0618:                        }
0619:                        if (toType == BigDecimal.class) {
0620:                            result = bigDecValue(value);
0621:                        }
0622:                        if (toType == String.class) {
0623:                            result = stringValue(value);
0624:                        }
0625:                    }
0626:                } else {
0627:                    if (toType.isPrimitive()) {
0628:                        result = primitiveDefaults.get(toType);
0629:                    }
0630:                }
0631:                return result;
0632:            }
0633:
0634:            /**
0635:             * Evaluates the given object as a double-precision floating-point number.
0636:             * 
0637:             * @param value
0638:             *            an object to interpret as a double
0639:             * @return the double value implied by the given object
0640:             * @throws NumberFormatException
0641:             *             if the given object can't be understood as a double
0642:             */
0643:            public static double doubleValue(Object value)
0644:                    throws NumberFormatException {
0645:                if (value == null) {
0646:                    return 0.0;
0647:                }
0648:                Class c = value.getClass();
0649:                if (c.getSuperclass() == Number.class) {
0650:                    return ((Number) value).doubleValue();
0651:                }
0652:                if (c == Boolean.class) {
0653:                    return ((Boolean) value).booleanValue() ? 1 : 0;
0654:                }
0655:                if (c == Character.class) {
0656:                    return ((Character) value).charValue();
0657:                }
0658:                String s = stringValue(value, true);
0659:
0660:                return (s.length() == 0) ? 0.0 : Double.parseDouble(s);
0661:            }
0662:
0663:            /**
0664:             * Returns true if a and b are equal. Either object may be null.
0665:             * 
0666:             * @param a
0667:             *            Object a
0668:             * @param b
0669:             *            Object b
0670:             * @return True if the objects are equal
0671:             */
0672:            public static boolean equal(final Object a, final Object b) {
0673:                if (a == b) {
0674:                    return true;
0675:                }
0676:
0677:                if ((a != null) && (b != null) && a.equals(b)) {
0678:                    return true;
0679:                }
0680:
0681:                return false;
0682:            }
0683:
0684:            /**
0685:             * Returns the constant from the NumericTypes interface that best expresses
0686:             * the type of an operation, which can be either numeric or not, on the two
0687:             * given types.
0688:             * 
0689:             * @param t1
0690:             *            type of one argument to an operator
0691:             * @param t2
0692:             *            type of the other argument
0693:             * @param canBeNonNumeric
0694:             *            whether the operator can be interpreted as non-numeric
0695:             * @return the appropriate constant from the NumericTypes interface
0696:             */
0697:            public static int getNumericType(int t1, int t2,
0698:                    boolean canBeNonNumeric) {
0699:                if (t1 == t2) {
0700:                    return t1;
0701:                }
0702:
0703:                if (canBeNonNumeric
0704:                        && (t1 == NONNUMERIC || t2 == NONNUMERIC || t1 == CHAR || t2 == CHAR)) {
0705:                    return NONNUMERIC;
0706:                }
0707:
0708:                if (t1 == NONNUMERIC) {
0709:                    t1 = DOUBLE; // Try to interpret strings as doubles...
0710:                }
0711:                if (t2 == NONNUMERIC) {
0712:                    t2 = DOUBLE; // Try to interpret strings as doubles...
0713:                }
0714:
0715:                if (t1 >= MIN_REAL_TYPE) {
0716:                    if (t2 >= MIN_REAL_TYPE) {
0717:                        return Math.max(t1, t2);
0718:                    }
0719:                    if (t2 < INT) {
0720:                        return t1;
0721:                    }
0722:                    if (t2 == BIGINT) {
0723:                        return BIGDEC;
0724:                    }
0725:                    return Math.max(DOUBLE, t1);
0726:                } else if (t2 >= MIN_REAL_TYPE) {
0727:                    if (t1 < INT) {
0728:                        return t2;
0729:                    }
0730:                    if (t1 == BIGINT) {
0731:                        return BIGDEC;
0732:                    }
0733:                    return Math.max(DOUBLE, t2);
0734:                } else {
0735:                    return Math.max(t1, t2);
0736:                }
0737:            }
0738:
0739:            /**
0740:             * Returns a constant from the NumericTypes interface that represents the
0741:             * numeric type of the given object.
0742:             * 
0743:             * @param value
0744:             *            an object that needs to be interpreted as a number
0745:             * @return the appropriate constant from the NumericTypes interface
0746:             */
0747:            public static int getNumericType(Object value) {
0748:                if (value != null) {
0749:                    Class c = value.getClass();
0750:                    if (c == Integer.class) {
0751:                        return INT;
0752:                    }
0753:                    if (c == Double.class) {
0754:                        return DOUBLE;
0755:                    }
0756:                    if (c == Boolean.class) {
0757:                        return BOOL;
0758:                    }
0759:                    if (c == Byte.class) {
0760:                        return BYTE;
0761:                    }
0762:                    if (c == Character.class) {
0763:                        return CHAR;
0764:                    }
0765:                    if (c == Short.class) {
0766:                        return SHORT;
0767:                    }
0768:                    if (c == Long.class) {
0769:                        return LONG;
0770:                    }
0771:                    if (c == Float.class) {
0772:                        return FLOAT;
0773:                    }
0774:                    if (c == BigInteger.class) {
0775:                        return BIGINT;
0776:                    }
0777:                    if (c == BigDecimal.class) {
0778:                        return BIGDEC;
0779:                    }
0780:                }
0781:                return NONNUMERIC;
0782:            }
0783:
0784:            /**
0785:             * Returns the constant from the NumericTypes interface that best expresses
0786:             * the type of a numeric operation on the two given objects.
0787:             * 
0788:             * @param v1
0789:             *            one argument to a numeric operator
0790:             * @param v2
0791:             *            the other argument
0792:             * @return the appropriate constant from the NumericTypes interface
0793:             */
0794:            public static int getNumericType(Object v1, Object v2) {
0795:                return getNumericType(v1, v2, false);
0796:            }
0797:
0798:            /**
0799:             * Returns the constant from the NumericTypes interface that best expresses
0800:             * the type of an operation, which can be either numeric or not, on the two
0801:             * given objects.
0802:             * 
0803:             * @param v1
0804:             *            one argument to an operator
0805:             * @param v2
0806:             *            the other argument
0807:             * @param canBeNonNumeric
0808:             *            whether the operator can be interpreted as non-numeric
0809:             * @return the appropriate constant from the NumericTypes interface
0810:             */
0811:            public static int getNumericType(Object v1, Object v2,
0812:                    boolean canBeNonNumeric) {
0813:                return getNumericType(getNumericType(v1), getNumericType(v2),
0814:                        canBeNonNumeric);
0815:            }
0816:
0817:            /**
0818:             * Returns true if object1 is equal to object2 in either the sense that they
0819:             * are the same object or, if both are non-null if they are equal in the
0820:             * <CODE>equals()</CODE> sense.
0821:             * 
0822:             * @param object1
0823:             *            First object to compare
0824:             * @param object2
0825:             *            Second object to compare
0826:             * 
0827:             * @return true if v1 == v2
0828:             */
0829:            public static boolean isEqual(Object object1, Object object2) {
0830:                boolean result = false;
0831:
0832:                if (object1 == object2) {
0833:                    result = true;
0834:                } else {
0835:                    if ((object1 != null) && object1.getClass().isArray()) {
0836:                        if ((object2 != null) && object2.getClass().isArray()
0837:                                && (object2.getClass() == object1.getClass())) {
0838:                            result = (Array.getLength(object1) == Array
0839:                                    .getLength(object2));
0840:                            if (result) {
0841:                                for (int i = 0, icount = Array
0842:                                        .getLength(object1); result
0843:                                        && (i < icount); i++) {
0844:                                    result = isEqual(Array.get(object1, i),
0845:                                            Array.get(object2, i));
0846:                                }
0847:                            }
0848:                        }
0849:                    } else {
0850:                        // Check for converted equivalence first, then equals()
0851:                        // equivalence
0852:                        result = (object1 != null)
0853:                                && (object2 != null)
0854:                                && ((compareWithConversion(object1, object2) == 0) || object1
0855:                                        .equals(object2));
0856:                    }
0857:                }
0858:                return result;
0859:            }
0860:
0861:            /**
0862:             * Evaluates the given object as a long integer.
0863:             * 
0864:             * @param value
0865:             *            an object to interpret as a long integer
0866:             * @return the long integer value implied by the given object
0867:             * @throws NumberFormatException
0868:             *             if the given object can't be understood as a long integer
0869:             */
0870:            public static long longValue(Object value)
0871:                    throws NumberFormatException {
0872:                if (value == null) {
0873:                    return 0L;
0874:                }
0875:                Class c = value.getClass();
0876:                if (c.getSuperclass() == Number.class) {
0877:                    return ((Number) value).longValue();
0878:                }
0879:                if (c == Boolean.class) {
0880:                    return ((Boolean) value).booleanValue() ? 1 : 0;
0881:                }
0882:                if (c == Character.class) {
0883:                    return ((Character) value).charValue();
0884:                }
0885:                return Long.parseLong(stringValue(value, true));
0886:            }
0887:
0888:            /**
0889:             * Creates a new instance using the current application's class resolver.
0890:             * Returns null if className is null.
0891:             * 
0892:             * @param className
0893:             *            The full class name
0894:             * @return The new object instance
0895:             */
0896:            public static Object newInstance(final String className) {
0897:                if (!Strings.isEmpty(className)) {
0898:                    try {
0899:                        Class c = Classes.resolveClass(className);
0900:                        if (c == null) {
0901:                            throw new WicketRuntimeException(
0902:                                    "Unable to create " + className);
0903:                        }
0904:                        return c.newInstance();
0905:                    } catch (ClassCastException e) {
0906:                        throw new WicketRuntimeException("Unable to create "
0907:                                + className, e);
0908:                    } catch (InstantiationException e) {
0909:                        throw new WicketRuntimeException("Unable to create "
0910:                                + className, e);
0911:                    } catch (IllegalAccessException e) {
0912:                        throw new WicketRuntimeException("Unable to create "
0913:                                + className, e);
0914:                    }
0915:                }
0916:                return null;
0917:            }
0918:
0919:            /**
0920:             * Returns a new Number object of an appropriate type to hold the given
0921:             * integer value. The type of the returned object is consistent with the
0922:             * given type argument, which is a constant from the NumericTypes interface.
0923:             * 
0924:             * @param type
0925:             *            the nominal numeric type of the result, a constant from the
0926:             *            NumericTypes interface
0927:             * @param value
0928:             *            the integer value to convert to a Number object
0929:             * @return a Number object with the given value, of type implied by the type
0930:             *         argument
0931:             */
0932:            public static Number newInteger(int type, long value) {
0933:                switch (type) {
0934:                case BOOL:
0935:                case CHAR:
0936:                case INT:
0937:                    return new Integer((int) value);
0938:
0939:                case FLOAT:
0940:                    if (value == value) {
0941:                        return new Float(value);
0942:                    }
0943:                    // else fall through:
0944:                case DOUBLE:
0945:                    if (value == value) {
0946:                        return new Double(value);
0947:                    }
0948:                    // else fall through:
0949:                case LONG:
0950:                    return new Long(value);
0951:
0952:                case BYTE:
0953:                    return new Byte((byte) value);
0954:
0955:                case SHORT:
0956:                    return new Short((short) value);
0957:
0958:                default:
0959:                    return BigInteger.valueOf(value);
0960:                }
0961:            }
0962:
0963:            /**
0964:             * Serializes an object into a byte array.
0965:             * 
0966:             * @param object
0967:             *            The object
0968:             * @return The serialized object
0969:             */
0970:            public static byte[] objectToByteArray(final Object object) {
0971:                try {
0972:                    final ByteArrayOutputStream out = new ByteArrayOutputStream();
0973:                    try {
0974:                        objectStreamFactory.newObjectOutputStream(out)
0975:                                .writeObject(object);
0976:                    } finally {
0977:                        out.close();
0978:                    }
0979:                    return out.toByteArray();
0980:                } catch (Exception e) {
0981:                    log.error("Error serializing object " + object.getClass()
0982:                            + " [object=" + object + "]", e);
0983:                }
0984:                return null;
0985:            }
0986:
0987:            /**
0988:             * Sets the strategy for determining the sizes of objects.
0989:             * 
0990:             * @param objectSizeOfStrategy
0991:             *            the strategy. Pass null to reset to the default.
0992:             */
0993:            public static void setObjectSizeOfStrategy(
0994:                    IObjectSizeOfStrategy objectSizeOfStrategy) {
0995:                if (objectSizeOfStrategy == null) {
0996:                    Objects.objectSizeOfStrategy = new SerializingObjectSizeOfStrategy();
0997:                } else {
0998:                    Objects.objectSizeOfStrategy = objectSizeOfStrategy;
0999:                }
1000:                log.info("using " + objectSizeOfStrategy
1001:                        + " for calculating object sizes");
1002:            }
1003:
1004:            /**
1005:             * Configure this utility class to use the provided
1006:             * {@link IObjectStreamFactory} instance.
1007:             * 
1008:             * @param objectStreamFactory
1009:             *            The factory instance to use. If you pass in null, the
1010:             *            {@link DefaultObjectStreamFactory default} will be set
1011:             *            (again). Pass null to reset to the default.
1012:             */
1013:            public static void setObjectStreamFactory(
1014:                    IObjectStreamFactory objectStreamFactory) {
1015:                if (objectStreamFactory == null) {
1016:                    Objects.objectStreamFactory = new IObjectStreamFactory.DefaultObjectStreamFactory();
1017:                } else {
1018:                    Objects.objectStreamFactory = objectStreamFactory;
1019:                }
1020:                log.info("using " + Objects.objectStreamFactory
1021:                        + " for creating object streams");
1022:            }
1023:
1024:            /**
1025:             * Computes the size of an object. Note that this is an estimation, never an
1026:             * absolute accurate size.
1027:             * 
1028:             * @param object
1029:             *            Object to compute size of
1030:             * @return The size of the object in bytes
1031:             */
1032:            public static long sizeof(final Object object) {
1033:                return objectSizeOfStrategy.sizeOf(object);
1034:            }
1035:
1036:            /**
1037:             * Evaluates the given object as a String.
1038:             * 
1039:             * @param value
1040:             *            an object to interpret as a String
1041:             * @return the String value implied by the given object as returned by the
1042:             *         toString() method, or "null" if the object is null.
1043:             */
1044:            public static String stringValue(Object value) {
1045:                return stringValue(value, false);
1046:            }
1047:
1048:            /**
1049:             * returns hashcode of the objects by calling obj.hashcode(). safe to use
1050:             * when obj is null.
1051:             * 
1052:             * @param obj
1053:             * @return hashcode of the object or 0 if obj is null
1054:             */
1055:            // TODO when on Java 5, we can use Object... obj
1056:            public static int hashCode(final Object[] obj) {
1057:                if (obj == null || obj.length == 0) {
1058:                    return 0;
1059:                }
1060:                int result = 37;
1061:                for (int i = obj.length - 1; i > -1; i--) {
1062:                    result = 37 * result
1063:                            + (obj[i] != null ? obj[i].hashCode() : 0);
1064:                }
1065:                return result;
1066:            }
1067:
1068:            /**
1069:             * Evaluates the given object as a String and trims it if the trim flag is
1070:             * true.
1071:             * 
1072:             * @param value
1073:             *            an object to interpret as a String
1074:             * @param trim
1075:             *            whether to trim the string
1076:             * @return the String value implied by the given object as returned by the
1077:             *         toString() method, or "null" if the object is null.
1078:             */
1079:            public static String stringValue(Object value, boolean trim) {
1080:                String result;
1081:
1082:                if (value == null) {
1083:                    result = "null";
1084:                } else {
1085:                    result = value.toString();
1086:                    if (trim) {
1087:                        result = result.trim();
1088:                    }
1089:                }
1090:                return result;
1091:            }
1092:
1093:            /**
1094:             * Instantiation not allowed
1095:             */
1096:            private Objects() {
1097:            }
1098:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.