📄 objects.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.wicket.util.lang;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.ObjectStreamClass;import java.io.OutputStream;import java.lang.reflect.Array;import java.math.BigDecimal;import java.math.BigInteger;import java.util.HashMap;import org.apache.wicket.Application;import org.apache.wicket.Component;import org.apache.wicket.WicketRuntimeException;import org.apache.wicket.application.IClassResolver;import org.apache.wicket.settings.IApplicationSettings;import org.apache.wicket.util.io.ByteCountingOutputStream;import org.apache.wicket.util.io.IObjectStreamFactory;import org.apache.wicket.util.io.IObjectStreamFactory.DefaultObjectStreamFactory;import org.apache.wicket.util.string.Strings;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * Object utilities. * * @author Jonathan Locke */public final class Objects{ /** * Interface that enables users to plugin the way object sizes are calculated with Wicket. */ public static interface IObjectSizeOfStrategy { /** * Computes the size of an object. This typically is an estimation, not an absolute accurate * size. * * @param object * Object to compute size of * @return The size of the object in bytes. */ long sizeOf(Object object); } /** * {@link IObjectSizeOfStrategy} that works by serializing the object to an instance of * {@link ByteCountingOutputStream}, which records the number of bytes written to it. Hence, * this gives the size of the object as it would be serialized,including all the overhead of * writing class headers etc. Not very accurate (the real memory consumption should be lower) * but the best we can do in a cheap way pre JDK 5. */ public static final class SerializingObjectSizeOfStrategy implements IObjectSizeOfStrategy { /** * @see org.apache.wicket.util.lang.Objects.IObjectSizeOfStrategy#sizeOf(java.lang.Object) */ public long sizeOf(Object object) { if (object == null) { return 0; } try { final ByteCountingOutputStream out = new ByteCountingOutputStream(); new ObjectOutputStream(out).writeObject(object); out.close(); return out.size(); } catch (IOException e) { return -1; } } } private static final class ReplaceObjectInputStream extends ObjectInputStream { private final ClassLoader classloader; private final HashMap replacedComponents; private ReplaceObjectInputStream(InputStream in, HashMap replacedComponents, ClassLoader classloader) throws IOException { super(in); this.replacedComponents = replacedComponents; this.classloader = classloader; enableResolveObject(true); } // This override is required to resolve classes inside in different // bundle, i.e. // The classes can be resolved by OSGI classresolver implementation protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { String className = desc.getName(); try { return Class.forName(className, true, classloader); } catch (ClassNotFoundException ex1) { // ignore this exception. log .debug("Class not found by using objects own classloader, trying the IClassResolver"); } Application application = Application.get(); IApplicationSettings applicationSettings = application.getApplicationSettings(); IClassResolver classResolver = applicationSettings.getClassResolver(); Class candidate = null; try { candidate = classResolver.resolveClass(className); if (candidate == null) { candidate = super.resolveClass(desc); } } catch (WicketRuntimeException ex) { if (ex.getCause() instanceof ClassNotFoundException) { throw (ClassNotFoundException)ex.getCause(); } } return candidate; } protected Object resolveObject(Object obj) throws IOException { Object replaced = replacedComponents.get(obj); if (replaced != null) { return replaced; } return super.resolveObject(obj); } } private static final class ReplaceObjectOutputStream extends ObjectOutputStream { private final HashMap replacedComponents; private ReplaceObjectOutputStream(OutputStream out, HashMap replacedComponents) throws IOException { super(out); this.replacedComponents = replacedComponents; enableReplaceObject(true); } protected Object replaceObject(Object obj) throws IOException { if (obj instanceof Component) { String name = ((Component)obj).getPath(); replacedComponents.put(name, obj); return name; } return super.replaceObject(obj); } } /** Type tag meaning java.math.BigDecimal. */ private static final int BIGDEC = 9; /** Type tag meaning java.math.BigInteger. */ private static final int BIGINT = 6; /** Type tag meaning boolean. */ private static final int BOOL = 0; /** Type tag meaning byte. */ private static final int BYTE = 1; /** Type tag meaning char. */ private static final int CHAR = 2; /** Type tag meaning double. */ private static final int DOUBLE = 8; /** Type tag meaning float. */ private static final int FLOAT = 7; /** Type tag meaning int. */ private static final int INT = 4; /** log. */ private static final Logger log = LoggerFactory.getLogger(Objects.class); /** Type tag meaning long. */ private static final int LONG = 5; /** * The smallest type tag that represents reals as opposed to integers. You can see whether a * type tag represents reals or integers by comparing the tag to this constant: all tags less * than this constant represent integers, and all tags greater than or equal to this constant * represent reals. Of course, you must also check for NONNUMERIC, which means it is not a * number at all. */ private static final int MIN_REAL_TYPE = FLOAT; /** Type tag meaning something other than a number. */ private static final int NONNUMERIC = 10; /** Type tag meaning short. */ private static final int SHORT = 3; /** defaults for primitives. */ private static final HashMap primitiveDefaults = new HashMap(); /** * The default object stream factory to use. Keep this as a static here opposed to in * Application, as the Application most likely isn't available in the threads we'll be using * this with. */ private static IObjectStreamFactory objectStreamFactory = new IObjectStreamFactory.DefaultObjectStreamFactory(); /** * Strategy for calculating sizes of objects. Note: I didn't make this an application setting as * we have enough of those already, and the typical way this probably would be used is that * install a different one according to the JDK version used, so varying them between * applications doesn't make a lot of sense. */ private static IObjectSizeOfStrategy objectSizeOfStrategy = new SerializingObjectSizeOfStrategy(); static { primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE); primitiveDefaults.put(Byte.TYPE, new Byte((byte)0)); primitiveDefaults.put(Short.TYPE, new Short((short)0)); primitiveDefaults.put(Character.TYPE, new Character((char)0)); primitiveDefaults.put(Integer.TYPE, new Integer(0)); primitiveDefaults.put(Long.TYPE, new Long(0L)); primitiveDefaults.put(Float.TYPE, new Float(0.0f)); primitiveDefaults.put(Double.TYPE, new Double(0.0)); primitiveDefaults.put(BigInteger.class, new BigInteger("0")); primitiveDefaults.put(BigDecimal.class, new BigDecimal(0.0)); } /** * Evaluates the given object as a BigDecimal. * * @param value * an object to interpret as a BigDecimal * @return the BigDecimal value implied by the given object * @throws NumberFormatException * if the given object can't be understood as a BigDecimal */ public static BigDecimal bigDecValue(Object value) throws NumberFormatException { if (value == null) { return BigDecimal.valueOf(0L); } Class c = value.getClass(); if (c == BigDecimal.class) { return (BigDecimal)value; } if (c == BigInteger.class) { return new BigDecimal((BigInteger)value); } if (c.getSuperclass() == Number.class) { return new BigDecimal(((Number)value).doubleValue()); } if (c == Boolean.class) { return BigDecimal.valueOf(((Boolean)value).booleanValue() ? 1 : 0); } if (c == Character.class) { return BigDecimal.valueOf(((Character)value).charValue()); } return new BigDecimal(stringValue(value, true)); } /** * Evaluates the given object as a BigInteger. * * @param value * an object to interpret as a BigInteger * @return the BigInteger value implied by the given object * @throws NumberFormatException * if the given object can't be understood as a BigInteger */ public static BigInteger bigIntValue(Object value) throws NumberFormatException { if (value == null) { return BigInteger.valueOf(0L); } Class c = value.getClass(); if (c == BigInteger.class) { return (BigInteger)value; } if (c == BigDecimal.class) { return ((BigDecimal)value).toBigInteger(); } if (c.getSuperclass() == Number.class) { return BigInteger.valueOf(((Number)value).longValue()); } if (c == Boolean.class) { return BigInteger.valueOf(((Boolean)value).booleanValue() ? 1 : 0); } if (c == Character.class) { return BigInteger.valueOf(((Character)value).charValue()); } return new BigInteger(stringValue(value, true)); } /** * Evaluates the given object as a boolean: if it is a Boolean object, it's easy; if it's a * Number or a Character, returns true for non-zero objects; and otherwise returns true for * non-null objects. * * @param value * an object to interpret as a boolean * @return the boolean value implied by the given object */ public static boolean booleanValue(Object value) { if (value == null) { return false; } Class c = value.getClass(); if (c == Boolean.class) { return ((Boolean)value).booleanValue(); } if (c == Character.class) { return ((Character)value).charValue() != 0; } if (value instanceof Number) { return ((Number)value).doubleValue() != 0; } return true; // non-null } /** * De-serializes an object from a byte array. * * @param data * The serialized object * @return The object */ public static Object byteArrayToObject(final byte[] data) { try { final ByteArrayInputStream in = new ByteArrayInputStream(data); try { return objectStreamFactory.newObjectInputStream(in).readObject(); } finally { in.close(); } } catch (ClassNotFoundException e) { throw new RuntimeException("Could not deserialize object using `" + objectStreamFactory.getClass().getName() + "` object factory", e); } catch (IOException e) { throw new RuntimeException("Could not deserialize object using `" + objectStreamFactory.getClass().getName() + "` object factory", e); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -