001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.xbean.recipe; 018 019 import org.apache.xbean.propertyeditor.PropertyEditors; 020 021 import java.lang.reflect.Modifier; 022 import java.lang.reflect.Constructor; 023 import java.util.Comparator; 024 import java.util.Map; 025 import java.util.List; 026 import java.util.Collections; 027 import java.util.ArrayList; 028 029 /** 030 * @version $Rev: 6687 $ $Date: 2005-12-28T21:08:56.733437Z $ 031 */ 032 public final class RecipeHelper { 033 private RecipeHelper() { 034 } 035 036 public static boolean hasDefaultConstructor(Class type) { 037 if (!Modifier.isPublic(type.getModifiers())) { 038 return false; 039 } 040 Constructor[] constructors = type.getConstructors(); 041 for (int i = 0; i < constructors.length; i++) { 042 Constructor constructor = constructors[i]; 043 if (Modifier.isPublic(constructor.getModifiers()) && 044 constructor.getParameterTypes().length == 0) { 045 return true; 046 } 047 } 048 return false; 049 } 050 051 public static boolean isSimpleType(Object o) { 052 return o == null || 053 o instanceof Boolean || 054 o instanceof Character || 055 o instanceof Byte || 056 o instanceof Short || 057 o instanceof Integer || 058 o instanceof Long || 059 o instanceof Float || 060 o instanceof Double || 061 o instanceof String || 062 o instanceof Recipe; 063 064 } 065 066 public static <K,V> List<Map.Entry<K,V>> prioritizeProperties(Map<K,V> properties) { 067 ArrayList<Map.Entry<K,V>> entries = new ArrayList<Map.Entry<K,V>>(properties.entrySet()); 068 Collections.sort(entries, new RecipeComparator()); 069 return entries; 070 } 071 072 public static boolean isInstance(Class type, Object instance) { 073 if (type.isPrimitive()) { 074 // for primitives the insance can't be null 075 if (instance == null) { 076 return false; 077 } 078 079 // verify instance is the correct wrapper type 080 if (type.equals(boolean.class)) { 081 return instance instanceof Boolean; 082 } else if (type.equals(char.class)) { 083 return instance instanceof Character; 084 } else if (type.equals(byte.class)) { 085 return instance instanceof Byte; 086 } else if (type.equals(short.class)) { 087 return instance instanceof Short; 088 } else if (type.equals(int.class)) { 089 return instance instanceof Integer; 090 } else if (type.equals(long.class)) { 091 return instance instanceof Long; 092 } else if (type.equals(float.class)) { 093 return instance instanceof Float; 094 } else if (type.equals(double.class)) { 095 return instance instanceof Double; 096 } else { 097 throw new AssertionError("Invalid primitve type: " + type); 098 } 099 } 100 101 return instance == null || type.isInstance(instance); 102 } 103 104 public static boolean isConvertable(Class type, Object propertyValue, ClassLoader classLoader) { 105 if (propertyValue instanceof Recipe) { 106 Recipe recipe = (Recipe) propertyValue; 107 return recipe.canCreate(type, classLoader); 108 } 109 return (propertyValue instanceof String && PropertyEditors.canConvert(type)); 110 } 111 112 public static boolean isAssignableFrom(Class expected, Class actual) { 113 if (expected.isPrimitive()) { 114 // verify actual is the correct wrapper type 115 if (expected.equals(boolean.class)) { 116 return actual.equals(Boolean.class); 117 } else if (expected.equals(char.class)) { 118 return actual.equals(Character.class); 119 } else if (expected.equals(byte.class)) { 120 return actual.equals(Byte.class); 121 } else if (expected.equals(short.class)) { 122 return actual.equals(Short.class); 123 } else if (expected.equals(int.class)) { 124 return actual.equals(Integer.class); 125 } else if (expected.equals(long.class)) { 126 return actual.equals(Long.class); 127 } else if (expected.equals(float.class)) { 128 return actual.equals(Float.class); 129 } else if (expected.equals(double.class)) { 130 return actual.equals(Double.class); 131 } else { 132 throw new AssertionError("Invalid primitve type: " + expected); 133 } 134 } 135 136 return expected.isAssignableFrom(actual); 137 } 138 139 public static class RecipeComparator implements Comparator<Object> { 140 public int compare(Object left, Object right) { 141 if (!(left instanceof Recipe) && !(right instanceof Recipe)) return 0; 142 if (left instanceof Recipe && !(right instanceof Recipe)) return 1; 143 if (!(left instanceof Recipe) && right instanceof Recipe) return -1; 144 145 float leftPriority = ((Recipe) left).getPriority(); 146 float rightPriority = ((Recipe) right).getPriority(); 147 148 if (leftPriority > rightPriority) return 1; 149 if (leftPriority < rightPriority) return -1; 150 return 0; 151 } 152 } 153 }