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 }