001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.messaging.amf.io.util;
022    
023    import java.beans.BeanInfo;
024    import java.beans.Introspector;
025    import java.beans.PropertyDescriptor;
026    import java.lang.reflect.Field;
027    import java.lang.reflect.Modifier;
028    import java.util.HashMap;
029    
030    import org.granite.util.ClassUtil;
031    
032    /**
033     * @author Franck WOLFF
034     */
035    public class DefaultActionScriptClassDescriptor extends ActionScriptClassDescriptor {
036    
037        public DefaultActionScriptClassDescriptor(String type, byte encoding) {
038            super(type, encoding);
039        }
040    
041        @Override
042        public void defineProperty(String name) {
043    
044            if (type.length() == 0 || instantiator != null)
045                properties.add(new MapProperty(converters, name));
046            else {
047                try {
048                    Class<?> clazz = ClassUtil.forName(type);
049    
050                    // Try to find public getter/setter.
051                    BeanInfo info = Introspector.getBeanInfo(clazz);
052                    PropertyDescriptor[] props = info.getPropertyDescriptors();
053                    for (PropertyDescriptor prop : props) {
054                        if (name.equals(prop.getName()) && prop.getWriteMethod() != null && prop.getReadMethod() != null) {
055                            properties.add(new MethodProperty(converters, name, prop.getWriteMethod(), prop.getReadMethod()));
056                            return;
057                        }
058                    }
059    
060                    // Try to find public field.
061                    Field field = clazz.getField(name);
062                    if (!Modifier.isStatic(field.getModifiers()) && !Modifier.isTransient(field.getModifiers()))
063                        properties.add(new FieldProperty(converters, field));
064    
065                }
066                catch (NoSuchFieldException e) {
067                    if ("uid".equals(name)) // ObjectProxy specific property...
068                        properties.add(new UIDProperty(converters));
069                    else
070                            throw new RuntimeException(e);
071                }
072                catch (Exception e) {
073                    throw new RuntimeException(e);
074                }
075            }
076        }
077    
078        @Override
079        public Object newJavaInstance() {
080    
081            if (type.length() == 0)
082                return new HashMap<String, Object>();
083    
084            String className = (instantiator != null ? instantiator : type);
085            try {
086                return ClassUtil.newInstance(className);
087            } catch (Exception e) {
088                throw new RuntimeException("Could not create instance of: " + className, e);
089            }
090        }
091    }