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 */
017package org.apache.xbean.spring.generator;
018
019import java.beans.PropertyEditor;
020import java.beans.PropertyEditorManager;
021import java.util.Collections;
022import java.util.HashMap;
023import java.util.Map;
024import java.util.List;
025import java.util.ArrayList;
026import java.util.Iterator;
027
028/**
029 * @author Dain Sundstrom
030 * @version $Id$
031 * @since 1.0
032 */
033public final class Utils {
034    public static final String XBEAN_ANNOTATION = "org.apache.xbean.XBean";
035    public static final String PROPERTY_ANNOTATION = "org.apache.xbean.Property";
036
037    private Utils() {
038    }
039
040    public static String decapitalise(String value) {
041        if (value == null || value.length() == 0) {
042            return value;
043        }
044        return value.substring(0, 1).toLowerCase() + value.substring(1);
045    }
046
047    public static boolean isSimpleType(Type type) {
048        if (type.isPrimitive()) {
049            return true;
050        }
051        if (type.isCollection()) {
052            return false;
053        }
054
055        String name = type.getName();
056        if (name.equals("java.lang.Class") ||
057                name.equals("javax.xml.namespace.QName")) {
058            return true;
059        }
060        return hasPropertyEditor(name);
061    }
062
063    private static boolean hasPropertyEditor(String type) {
064        Class theClass;
065        try {
066            theClass = loadClass(type);
067            // lets see if we can find a property editor for this type
068            PropertyEditor editor = PropertyEditorManager.findEditor(theClass);
069            return editor != null;
070        } catch (Throwable e) {
071            System.out.println("Warning, could not load class: " + type + ": " + e);
072            return false;
073        }
074    }
075
076    /**
077     * Attempts to load the class on the current thread context class loader or
078     * the class loader which loaded us
079     */
080    private static Class loadClass(String name) throws ClassNotFoundException {
081        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
082        if (contextClassLoader != null) {
083            try {
084                return contextClassLoader.loadClass(name);
085            } catch (ClassNotFoundException e) {
086            }
087        }
088        return Utils.class.getClassLoader().loadClass(name);
089    }
090
091    public static String getXsdType(Type type) {
092        String name = type.getName();
093        String xsdType = (String) XSD_TYPES.get(name);
094        if (xsdType == null) {
095            xsdType = "xs:string";
096        }
097        return xsdType;
098    }
099
100    public static final Map XSD_TYPES;
101
102    static {
103        // TODO check these XSD types are right...
104        Map map = new HashMap();
105        map.put(String.class.getName(), "xs:string");
106        map.put(Boolean.class.getName(), "xs:boolean");
107        map.put(boolean.class.getName(), "xs:boolean");
108        map.put(Byte.class.getName(), "xs:byte");
109        map.put(byte.class.getName(), "xs:byte");
110        map.put(Short.class.getName(), "xs:short");
111        map.put(short.class.getName(), "xs:short");
112        map.put(Integer.class.getName(), "xs:integer");
113        map.put(int.class.getName(), "xs:integer");
114        map.put(Long.class.getName(), "xs:long");
115        map.put(long.class.getName(), "xs:long");
116        map.put(Float.class.getName(), "xs:float");
117        map.put(float.class.getName(), "xs:float");
118        map.put(Double.class.getName(), "xs:double");
119        map.put(double.class.getName(), "xs:double");
120        map.put(java.util.Date.class.getName(), "xs:date");
121        map.put(java.sql.Date.class.getName(), "xs:date");
122        map.put("javax.xml.namespace.QName", "xs:QName");
123        XSD_TYPES = Collections.unmodifiableMap(map);
124    }
125
126    public static List findImplementationsOf(NamespaceMapping namespaceMapping, Type type) {
127        List elements = new ArrayList();
128        String nestedTypeName = type.getName();
129        for (Iterator iter = namespaceMapping.getElements().iterator(); iter.hasNext();) {
130            ElementMapping element = (ElementMapping) iter.next();
131            if (element.getClassName().equals(nestedTypeName) ||
132                element.getInterfaces().contains(nestedTypeName) ||
133                element.getSuperClasses().contains(nestedTypeName)) 
134            {
135                elements.add(element);
136            }
137        }
138        return elements;
139    }
140}