⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openconverter.java

📁 Mobile 应用程序使用 Java Micro Edition (Java ME) 平台
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
            }	    if (annotatedConstrList.isEmpty())		return "no constructor has @ConstructorProperties annotation";            annotatedConstructors = newList();            // Now check that all the annotated constructors are valid            // and throw an exception if not.            // First link the itemNames to their getter indexes.            Map<String, Integer> getterMap = newMap();            String[] itemNames = getItemNames();            for (int i = 0; i < itemNames.length; i++)                getterMap.put(itemNames[i], i);            // Run through the constructors making the checks in the spec.            // For each constructor, remember the correspondence between its            // parameters and the items.  The int[] for a constructor says            // what parameter index should get what item.  For example,            // if element 0 is 2 then that means that item 0 in the            // CompositeData goes to parameter 2 of the constructor.  If an            // element is -1, that item isn't given to the constructor.            // Also remember the set of properties in that constructor            // so we can test unambiguity.            Set<BitSet> getterIndexSets = newSet();            for (Constructor constr : annotatedConstrList) {                String[] propertyNames =                    constr.getAnnotation(propertyNamesClass).value();                Type[] paramTypes = constr.getGenericParameterTypes();                if (paramTypes.length != propertyNames.length) {                    final String msg =                        "Number of constructor params does not match " +                        "@ConstructorProperties annotation: " + constr;                    throw new InvalidObjectException(msg);                }                // Work around bug 6710498 (really caused by 5041784):                for (int i = 0; i < paramTypes.length; i++)                    paramTypes[i] = fixType(paramTypes[i]);                int[] paramIndexes = new int[getters.length];                for (int i = 0; i < getters.length; i++)                    paramIndexes[i] = -1;                BitSet present = new BitSet();                for (int i = 0; i < propertyNames.length; i++) {                    String propertyName = propertyNames[i];                    if (!getterMap.containsKey(propertyName)) {                        String msg =                            "@ConstructorProperties includes name " + propertyName +                            " which does not correspond to a property";                        for (String getterName : getterMap.keySet()) {                            if (getterName.equalsIgnoreCase(propertyName)) {                                msg += " (differs only in case from property " +                                        getterName + ")";                            }                        }                        msg += ": " + constr;                        throw new InvalidObjectException(msg);                    }                    int getterIndex = getterMap.get(propertyName);                    paramIndexes[getterIndex] = i;                    if (present.get(getterIndex)) {                        final String msg =                            "@ConstructorProperties contains property " +                            propertyName + " more than once: " + constr;                        throw new InvalidObjectException(msg);                    }                    present.set(getterIndex);                    Method getter = getters[getterIndex];                    Type propertyType = getter.getGenericReturnType();                    if (!propertyType.equals(paramTypes[i])) {                        final String msg =                            "@ConstructorProperties gives property " + propertyName +                            " of type " + propertyType + " for parameter " +                            " of type " + paramTypes[i] + ": " + constr;                        throw new InvalidObjectException(msg);                    }                }                if (!getterIndexSets.add(present)) {                    final String msg =                        "More than one constructor has a @ConstructorProperties " +                        "annotation with this set of names: " +                        Arrays.toString(propertyNames);                    throw new InvalidObjectException(msg);                }                Constr c = new Constr(constr, paramIndexes, present);                annotatedConstructors.add(c);            }            /* Check that no possible set of items could lead to an ambiguous             * choice of constructor (spec requires this check).  For any             * pair of constructors, their union would be the minimal             * ambiguous set.  If this set itself corresponds to a constructor,             * there is no ambiguity for that pair.  In the usual case, one             * of the constructors is a superset of the other so the union is             * just the bigger constuctor.	     *	     * The algorithm here is quadratic in the number of constructors	     * with a @ConstructorProperties annotation.  Typically this corresponds	     * to the number of versions of the class there have been.  Ten	     * would already be a large number, so although it's probably	     * possible to have an O(n lg n) algorithm it wouldn't be	     * worth the complexity.             */            for (BitSet a : getterIndexSets) {                boolean seen = false;                for (BitSet b : getterIndexSets) {                    if (a == b)                        seen = true;                    else if (seen) {                        BitSet u = new BitSet();                        u.or(a); u.or(b);                        if (!getterIndexSets.contains(u)) {                            Set<String> names = new TreeSet<String>();                            for (int i = u.nextSetBit(0); i >= 0;                                 i = u.nextSetBit(i+1))                                names.add(itemNames[i]);                            final String msg =                                "Constructors with @ConstructorProperties annotation " +                                " would be ambiguous for these items: " +                                names;                            throw new InvalidObjectException(msg);                        }                    }                }            }	    return null; // success!	}        Object fromCompositeData(MXBeanLookup lookup, CompositeData cd,                                 String[] itemNames,                                 OpenConverter[] converters)                throws InvalidObjectException {            // The CompositeData might come from an earlier version where            // not all the items were present.  We look for a constructor            // that accepts just the items that are present.  Because of            // the ambiguity check in applicable(), we know there must be            // at most one maximally applicable constructor.            CompositeType ct = cd.getCompositeType();            BitSet present = new BitSet();            for (int i = 0; i < itemNames.length; i++) {                if (ct.getType(itemNames[i]) != null)                    present.set(i);            }            Constr max = null;            for (Constr constr : annotatedConstructors) {                if (subset(constr.presentParams, present) &&                        (max == null ||                         subset(max.presentParams, constr.presentParams)))                    max = constr;            }            if (max == null) {                final String msg =                    "No constructor has a @ConstructorProperties for this set of " +                    "items: " + ct.keySet();                throw new InvalidObjectException(msg);            }            Object[] params = new Object[max.presentParams.cardinality()];            for (int i = 0; i < itemNames.length; i++) {                if (!max.presentParams.get(i))                    continue;                Object openItem = cd.get(itemNames[i]);                Object javaItem = converters[i].fromOpenValue(lookup, openItem);                int index = max.paramIndexes[i];                if (index >= 0)                    params[index] = javaItem;            }	    try {		return max.constructor.newInstance(params);	    } catch (Exception e) {		final String msg =		    "Exception constructing " + getTargetClass().getName();                throw invalidObjectException(msg, e);	    }        }        private static boolean subset(BitSet sub, BitSet sup) {            BitSet subcopy = (BitSet) sub.clone();            subcopy.andNot(sup);            return subcopy.isEmpty();        }        private static class Constr {            final Constructor constructor;            final int[] paramIndexes;            final BitSet presentParams;            Constr(Constructor constructor, int[] paramIndexes,                   BitSet presentParams) {                this.constructor = constructor;                this.paramIndexes = paramIndexes;                this.presentParams = presentParams;            }        }        private List<Constr> annotatedConstructors;    }    /** Builder for when the target class is an interface and contains	no methods other than getters.  Then we can make an instance	using a dynamic proxy that forwards the getters to the source	CompositeData.  */    private static final class CompositeBuilderViaProxy	    extends CompositeBuilder {	CompositeBuilderViaProxy(Class targetClass, String[] itemNames) {	    super(targetClass, itemNames);	}	String applicable(Method[] getters) {	    Class targetClass = getTargetClass();	    if (!targetClass.isInterface())		return "not an interface";            Set<Method> methods =                newSet(Arrays.asList(targetClass.getMethods()));            methods.removeAll(Arrays.asList(getters));            /* If the interface has any methods left over, they better be             * public methods that are already present in java.lang.Object.             */            String bad = null;            for (Method m : methods) {                String mname = m.getName();                Class[] mparams = m.getParameterTypes();                try {                    Method om = Object.class.getMethod(mname, mparams);                    if (!Modifier.isPublic(om.getModifiers()))                        bad = mname;                } catch (NoSuchMethodException e) {                    bad = mname;                }                /* We don't catch SecurityException since it shouldn't                 * happen for a method in Object and if it does we would                 * like to know about it rather than mysteriously complaining.                 */            }	    if (bad != null)		return "contains methods other than getters (" + bad + ")";	    return null; // success!	}	final Object fromCompositeData(MXBeanLookup lookup, CompositeData cd,                                 String[] itemNames,                                 OpenConverter[] converters) {	    final Class targetClass = getTargetClass();	    return		Proxy.newProxyInstance(targetClass.getClassLoader(),				       new Class[] {targetClass},				       new CompositeDataInvocationHandler(cd));	}    }    static InvalidObjectException invalidObjectException(String msg,                                                         Throwable cause) {        return EnvHelp.initCause(new InvalidObjectException(msg), cause);    }    static InvalidObjectException invalidObjectException(Throwable cause) {        return invalidObjectException(cause.getMessage(), cause);    }    static OpenDataException openDataException(String msg, Throwable cause) {        return EnvHelp.initCause(new OpenDataException(msg), cause);    }    static OpenDataException openDataException(Throwable cause) {        return openDataException(cause.getMessage(), cause);    }    static void mustBeComparable(Class collection, Type element)            throws OpenDataException {        if (!(element instanceof Class)            || !Comparable.class.isAssignableFrom((Class<?>) element)) {            final String msg =                "Parameter class " + element + " of " +                collection.getName() + " does not implement " +                Comparable.class.getName();            throw new OpenDataException(msg);        }    }    /**     * Utility method to take a string and convert it to normal Java variable     * name capitalization.  This normally means converting the first     * character from upper case to lower case, but in the (unusual) special     * case when there is more than one character and both the first and     * second characters are upper case, we leave it alone.     * <p>     * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays     * as "URL".     *     * @param  name The string to be decapitalized.     * @return  The decapitalized version of the string.     */    public static String decapitalize(String name) {        if (name == null || name.length() == 0) {            return name;        }        int offset1 = Character.offsetByCodePoints(name, 0, 1);        // Should be name.offsetByCodePoints but 6242664 makes this fail        if (offset1 < name.length() &&                Character.isUpperCase(name.codePointAt(offset1)))            return name;        return name.substring(0, offset1).toLowerCase() +               name.substring(offset1);    }    /**     * Reverse operation for java.beans.Introspector.decapitalize.  For any s,     * capitalize(decapitalize(s)).equals(s).  The reverse is not true:     * e.g. capitalize("uRL") produces "URL" which is unchanged by     * decapitalize.     */    static String capitalize(String name) {        if (name == null || name.length() == 0)            return name;        int offset1 = name.offsetByCodePoints(0, 1);        return name.substring(0, offset1).toUpperCase() +               name.substring(offset1);    }    public static String propertyName(Method m) {	String rest = null;	String name = m.getName();	if (name.startsWith("get"))	    rest = name.substring(3);	else if (name.startsWith("is") && m.getReturnType() == boolean.class)	    rest = name.substring(2);	if (rest == null || rest.length() == 0	    || m.getParameterTypes().length > 0	    || m.getReturnType() == void.class	    || name.equals("getClass"))	    return null;	return rest;    }    private static String typeName(Type t) {        if (t instanceof Class<?>) {            Class<?> c = (Class<?>) t;            if (c.isArray())                return typeName(c.getComponentType()) + "[]";            else                return c.getName();        }        return t.toString();    }    // Work around for bug 5041784, where types like String[] are sometimes    // represented as GenericArrayType instead of Class.    private static Type fixType(Type t) {        if (!(t instanceof GenericArrayType))            return t;        GenericArrayType gat = (GenericArrayType) t;        Type ultimate = ultimateComponentType(gat);        if (!(ultimate instanceof Class<?>))            return t;        Class<?> component = (Class<?>) fixType(gat.getGenericComponentType());        return Array.newInstance(component, 0).getClass();    }    private static Type ultimateComponentType(GenericArrayType gat) {        Type component = gat.getGenericComponentType();        if (component instanceof GenericArrayType)            return ultimateComponentType((GenericArrayType) component);        else            return component;    }    private final static Map<Type, Type> inProgress = newIdentityHashMap();    // really an IdentityHashSet but that doesn't exist}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -