Information

0
Story Points

Technologies

Decompiled Java File
package org.exolab.castor.xml;

import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import org.castor.xml.InternalContext;
import org.castor.xml.JavaNaming;
import org.castor.xml.XMLNaming;
import org.exolab.castor.mapping.CollectionHandler;
import org.exolab.castor.mapping.FieldHandler;
import org.exolab.castor.mapping.FieldHandlerFactory;
import org.exolab.castor.mapping.GeneralizedFieldHandler;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.mapping.TypeConvertor;
import org.exolab.castor.mapping.loader.CollectionHandlers;
import org.exolab.castor.mapping.loader.FieldHandlerImpl;
import org.exolab.castor.mapping.loader.TypeInfo;
import org.exolab.castor.util.ReflectionUtil;
import org.exolab.castor.xml.IntrospectedXMLClassDescriptor;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.NodeType;
import org.exolab.castor.xml.XMLClassDescriptor;
import org.exolab.castor.xml.descriptors.CoreDescriptors;
import org.exolab.castor.xml.handlers.ContainerFieldHandler;
import org.exolab.castor.xml.handlers.DateFieldHandler;
import org.exolab.castor.xml.handlers.DefaultFieldHandlerFactory;
import org.exolab.castor.xml.util.ContainerElement;
import org.exolab.castor.xml.util.XMLClassDescriptorImpl;
import org.exolab.castor.xml.util.XMLFieldDescriptorImpl;

public final class Introspector {
   private static final FieldHandlerFactory DEFAULT_HANDLER_FACTORY = new DefaultFieldHandlerFactory();
   private static final Class[] EMPTY_CLASS_ARGS = new Class[0];
   private static final String LIST = "java.util.List";
   private static final String MAP = "java.util.Map";
   private static final String SET_COLLECTION = "java.util.Set";
   private static final String COLLECTION_WRAPPER_PREFIX = "##container_for_";
   private static final boolean WRAP_COLLECTIONS_DEFAULT = false;
   private static final Class[] COLLECTIONS = loadCollections();
   private static XMLNaming _defaultNaming = null;
   private XMLNaming _xmlNaming;
   private NodeType _primitiveNodeType;
   private boolean _wrapCollectionsInContainer;
   private Vector _handlerFactoryList;
   private Hashtable _handlerFactoryMap;
   private boolean _saveMapKeys;
   private ClassLoader _classLoader;
   private JavaNaming _javaNaming;
   private InternalContext _internalContext;

   public Introspector() {
      this((ClassLoader)null);
   }

   public Introspector(ClassLoader classLoader) {
      this._xmlNaming = null;
      this._primitiveNodeType = null;
      this._wrapCollectionsInContainer = false;
      this._handlerFactoryList = null;
      this._handlerFactoryMap = null;
      this._saveMapKeys = true;
      this._classLoader = null;
      this._classLoader = classLoader;
      this.init();
   }

   private void init() {
      if(this._internalContext != null) {
         this._javaNaming = this._internalContext.getJavaNaming();
         this._xmlNaming = this._internalContext.getXMLNaming();
         this.setPrimitiveNodeType(this._internalContext.getPrimitiveNodeType());
         this._wrapCollectionsInContainer = this._internalContext.getBooleanProperty("org.exolab.castor.xml.introspector.wrapCollections").booleanValue();
         this._saveMapKeys = this._internalContext.getBooleanProperty("org.exolab.castor.xml.saveMapKeys").booleanValue();
      }

   }

   public void setInternalContext(InternalContext internalContext) {
      this._internalContext = internalContext;
      this.init();
   }

   public synchronized void addFieldHandlerFactory(FieldHandlerFactory factory) {
      if(factory == null) {
         String err = "The argument \'factory\' must not be null.";
         throw new IllegalArgumentException(err);
      } else {
         if(this._handlerFactoryList == null) {
            this._handlerFactoryList = new Vector();
         }

         this._handlerFactoryList.addElement(factory);
         this.registerHandlerFactory(factory);
      }
   }

   public NodeType getPrimitiveNodeType() {
      return this._primitiveNodeType;
   }

   public XMLClassDescriptor generateClassDescriptor(Class c) throws MarshalException {
      return this.generateClassDescriptor(c, (PrintWriter)null);
   }

   public XMLClassDescriptor generateClassDescriptor(Class c, PrintWriter errorWriter) throws MarshalException {
      if(c == null) {
         return null;
      } else if(c.isArray()) {
         return null;
      } else if(c != Void.class && c != Class.class && c != Object.class) {
         XMLClassDescriptor coreDesc = CoreDescriptors.getDescriptor(c);
         if(coreDesc != null) {
            return coreDesc;
         } else {
            IntrospectedXMLClassDescriptor classDesc = new IntrospectedXMLClassDescriptor(c);
            Method[] methods = c.getMethods();
            ArrayList dateDescriptors = new ArrayList(3);
            Hashtable methodSets = new Hashtable();
            int methodCount = 0;
            Class superClass = c.getSuperclass();
            Class[] interfaces = c.getInterfaces();

            boolean handler;
            Method type;
            Class var47;
            for(int enumeration = 0; enumeration < methods.length; ++enumeration) {
               Method mx = methods[enumeration];
               Class fieldDesc = mx.getDeclaringClass();
               String var44;
               if(fieldDesc != c) {
                  if(!fieldDesc.isInterface()) {
                     continue;
                  }

                  if(interfaces.length > 0) {
                     handler = false;

                     for(int dfh = 0; dfh < interfaces.length; ++dfh) {
                        if(interfaces[dfh] == fieldDesc) {
                           handler = true;
                           break;
                        }
                     }

                     if(!handler) {
                        continue;
                     }
                  }
               } else if(superClass != null) {
                  Class[] var42 = mx.getParameterTypes();
                  var44 = mx.getName();
                  type = null;

                  try {
                     type = superClass.getMethod(var44, var42);
                  } catch (NoSuchMethodException var31) {
                     ;
                  }

                  if(type != null) {
                     continue;
                  }
               }

               if((mx.getModifiers() & 8) == 0) {
                  String var43 = mx.getName();
                  Introspector.MethodSet modifiers;
                  String var49;
                  if(var43.startsWith("get")) {
                     if(mx.getParameterTypes().length == 0) {
                        ++methodCount;
                        var47 = mx.getReturnType();
                        if(var47 != null && isDescriptable(var47)) {
                           var49 = var43.substring(3);
                           var49 = this._javaNaming.toJavaMemberName(var49);
                           modifiers = (Introspector.MethodSet)methodSets.get(var49);
                           if(modifiers == null) {
                              modifiers = new Introspector.MethodSet(var49);
                              methodSets.put(var49, modifiers);
                           }

                           modifiers._get = mx;
                        }
                     }
                  } else if(var43.startsWith("is")) {
                     if(mx.getParameterTypes().length == 0) {
                        var47 = mx.getReturnType();
                        if(var47 != null) {
                           if(var47.isPrimitive()) {
                              if(var47 != Boolean.TYPE) {
                                 continue;
                              }
                           } else if(var47 != Boolean.class) {
                              continue;
                           }

                           ++methodCount;
                           var49 = var43.substring("is".length());
                           var49 = this._javaNaming.toJavaMemberName(var49);
                           modifiers = (Introspector.MethodSet)methodSets.get(var49);
                           if(modifiers == null) {
                              modifiers = new Introspector.MethodSet(var49);
                              methodSets.put(var49, modifiers);
                           }

                           modifiers._get = mx;
                        }
                     }
                  } else {
                     Introspector.MethodSet var46;
                     if(var43.startsWith("add")) {
                        if(mx.getParameterTypes().length == 1) {
                           ++methodCount;
                           if(isDescriptable(mx.getParameterTypes()[0])) {
                              var44 = var43.substring(3);
                              var44 = this._javaNaming.toJavaMemberName(var44);
                              var46 = (Introspector.MethodSet)methodSets.get(var44);
                              if(var46 == null) {
                                 var46 = new Introspector.MethodSet(var44);
                                 methodSets.put(var44, var46);
                              }

                              var46._add = mx;
                           }
                        }
                     } else if(var43.startsWith("set")) {
                        if(mx.getParameterTypes().length == 1) {
                           ++methodCount;
                           if(isDescriptable(mx.getParameterTypes()[0])) {
                              var44 = var43.substring(3);
                              var44 = this._javaNaming.toJavaMemberName(var44);
                              var46 = (Introspector.MethodSet)methodSets.get(var44);
                              if(var46 == null) {
                                 var46 = new Introspector.MethodSet(var44);
                                 methodSets.put(var44, var46);
                              }

                              var46._set = mx;
                           }
                        }
                     } else if(var43.startsWith("create") && mx.getParameterTypes().length == 0) {
                        var47 = mx.getReturnType();
                        if(isDescriptable(var47)) {
                           var49 = var43.substring("create".length());
                           var49 = this._javaNaming.toJavaMemberName(var49);
                           modifiers = (Introspector.MethodSet)methodSets.get(var49);
                           if(modifiers == null) {
                              modifiers = new Introspector.MethodSet(var49);
                              methodSets.put(var49, modifiers);
                           }

                           modifiers._create = mx;
                        }
                     }
                  }
               }
            }

            Enumeration var34 = methodSets.elements();

            boolean isCollection;
            FieldHandlerFactory typeInfo;
            ContainerFieldHandler handler1;
            while(var34.hasMoreElements()) {
               Introspector.MethodSet var35 = (Introspector.MethodSet)var34.nextElement();
               String var38 = this._xmlNaming.toXMLName(var35._fieldName);
               handler = false;
               var47 = null;
               if(var35._add != null) {
                  var47 = var35._add.getParameterTypes()[0];
                  handler = true;
               }

               if(var47 == null) {
                  if(var35._get != null) {
                     var47 = var35._get.getReturnType();
                  } else {
                     if(var35._set == null) {
                        continue;
                     }

                     var47 = var35._set.getParameterTypes()[0];
                  }
               }

               handler = handler || isCollection(var47);
               type = null;
               CollectionHandler var51 = null;
               if(handler && var35._add == null) {
                  try {
                     var51 = CollectionHandlers.getHandler(var47);
                  } catch (MappingException var30) {
                     ;
                  }

                  if(var47.isArray()) {
                     if(var47.getComponentType() == Byte.TYPE) {
                        var51 = null;
                     } else {
                        var47 = var47.getComponentType();
                     }
                  }
               }

               TypeInfo var54 = new TypeInfo(var47, (TypeConvertor)null, (TypeConvertor)null, false, (Object)null, var51);
               Object type1 = null;
               isCollection = false;

               try {
                  type1 = new FieldHandlerImpl(var35._fieldName, (Method[])null, (Method[])null, var35._get, var35._set, var54);
                  if(var35._add != null) {
                     ((FieldHandlerImpl)type1).setAddMethod(var35._add);
                  }

                  if(var35._create != null) {
                     ((FieldHandlerImpl)type1).setCreateMethod(var35._create);
                  }

                  if(handler && this._saveMapKeys && isMapCollection(var47)) {
                     ((FieldHandlerImpl)type1).setConvertFrom(new Introspector.IdentityConvertor());
                  }

                  typeInfo = this.getHandlerFactory(var47);
                  if(typeInfo != null) {
                     GeneralizedFieldHandler colHandler = typeInfo.createFieldHandler(var47);
                     if(colHandler != null) {
                        colHandler.setFieldHandler((FieldHandler)type1);
                        type1 = colHandler;
                        isCollection = true;
                        if(colHandler.getFieldType() != null) {
                           var47 = colHandler.getFieldType();
                        }
                     }
                  }
               } catch (MappingException var33) {
                  throw new MarshalException(var33);
               }

               XMLFieldDescriptorImpl var53 = this.createFieldDescriptor(var47, var35._fieldName, var38);
               if(handler) {
                  var53.setMultivalued(true);
                  var53.setNodeType(NodeType.Element);
               }

               if(Date.class.isAssignableFrom(var47) && !isCollection) {
                  dateDescriptors.add(var53);
               }

               var53.setHandler((FieldHandler)type1);
               var53.setUseParentsNamespace(true);
               if(handler && this._wrapCollectionsInContainer) {
                  String var56 = "##container_for_" + var35._fieldName;
                  Class fieldName = ContainerElement.class;
                  XMLClassDescriptorImpl xmlName = new XMLClassDescriptorImpl(fieldName);
                  xmlName.addFieldDescriptor(var53);
                  var53.setXMLName((String)null);
                  var53.setMatches("*");
                  handler1 = new ContainerFieldHandler((FieldHandler)type1);
                  var53.setHandler(handler1);
                  var53 = this.createFieldDescriptor(fieldName, var56, var38);
                  var53.setClassDescriptor(xmlName);
                  var53.setHandler(handler1);
                  var53.setUseParentsNamespace(true);
               }

               classDesc.addFieldDescriptor(var53);
            }

            Class var57;
            if(methodCount == 0) {
               Field[] var36 = c.getFields();
               Hashtable var39 = new Hashtable();

               for(int var45 = 0; var45 < var36.length; ++var45) {
                  Field var60 = var36[var45];
                  var57 = var60.getDeclaringClass();
                  if(var57 != c) {
                     if(!var57.isInterface()) {
                        continue;
                     }

                     if(interfaces.length > 0) {
                        boolean var55 = false;

                        for(int var50 = 0; var50 < interfaces.length; ++var50) {
                           if(interfaces[var50] == var57) {
                              var55 = true;
                              break;
                           }
                        }

                        if(!var55) {
                           continue;
                        }
                     }
                  }

                  int var61 = var60.getModifiers();
                  if(!Modifier.isTransient(var61) && (!Modifier.isFinal(var61) || !Modifier.isStatic(var61))) {
                     Class var52 = var60.getType();
                     if(isDescriptable(var52)) {
                        isCollection = isCollection(var52);
                        typeInfo = null;
                        CollectionHandler var58 = null;
                        if(isCollection) {
                           try {
                              var58 = CollectionHandlers.getHandler(var52);
                           } catch (MappingException var29) {
                              ;
                           }

                           if(var52.isArray()) {
                              if(var52.getComponentType() == Byte.TYPE) {
                                 var58 = null;
                              } else {
                                 var52 = var52.getComponentType();
                              }
                           }
                        }

                        String var62 = var60.getName();
                        String var64 = this._xmlNaming.toXMLName(var62);
                        TypeInfo var59 = new TypeInfo(var52, (TypeConvertor)null, (TypeConvertor)null, false, (Object)null, var58);
                        handler1 = null;
                        boolean customHandler = false;

                        Object var65;
                        try {
                           var65 = new FieldHandlerImpl(var60, var59);
                           if(isCollection && this._saveMapKeys && isMapCollection(var52)) {
                              ((FieldHandlerImpl)var65).setConvertFrom(new Introspector.IdentityConvertor());
                           }

                           FieldHandlerFactory fieldDesc1 = this.getHandlerFactory(var52);
                           if(fieldDesc1 != null) {
                              GeneralizedFieldHandler gfh = fieldDesc1.createFieldHandler(var52);
                              if(gfh != null) {
                                 gfh.setFieldHandler((FieldHandler)var65);
                                 var65 = gfh;
                                 customHandler = true;
                                 if(gfh.getFieldType() != null) {
                                    var52 = gfh.getFieldType();
                                 }
                              }
                           }
                        } catch (MappingException var32) {
                           throw new MarshalException(var32);
                        }

                        XMLFieldDescriptorImpl var66 = this.createFieldDescriptor(var52, var62, var64);
                        if(isCollection) {
                           var66.setNodeType(NodeType.Element);
                           var66.setMultivalued(true);
                        }

                        var39.put(var64, var66);
                        classDesc.addFieldDescriptor(var66);
                        var66.setHandler((FieldHandler)var65);
                        var66.setUseParentsNamespace(true);
                        if(Date.class.isAssignableFrom(var52) && !customHandler) {
                           dateDescriptors.add(var66);
                        }
                     }
                  }
               }
            }

            if(dateDescriptors != null) {
               for(int var37 = 0; var37 < dateDescriptors.size(); ++var37) {
                  XMLFieldDescriptorImpl var41 = (XMLFieldDescriptorImpl)dateDescriptors.get(var37);
                  FieldHandler var48 = var41.getHandler();
                  var41.setImmutable(true);
                  DateFieldHandler var63 = new DateFieldHandler(var48);
                  var57 = var41.getFieldType();
                  if(java.sql.Date.class.isAssignableFrom(var57)) {
                     var63.setUseSQLDate(true);
                  }

                  var41.setHandler(var63);
               }
            }

            if(superClass != null && superClass != Void.class && superClass != Object.class && superClass != Class.class) {
               try {
                  XMLClassDescriptor var40 = this.generateClassDescriptor(superClass, errorWriter);
                  if(var40 != null) {
                     classDesc.setExtends(var40);
                  }
               } catch (MarshalException var28) {
                  ;
               }
            }

            return classDesc;
         }
      } else {
         throw new MarshalException("The marshaller cannot marshal/unmarshal types of Void.class, Class.class or Object.class");
      }
   }

   public synchronized boolean removeFieldHandlerFactory(FieldHandlerFactory factory) {
      if(factory == null) {
         String var4 = "The argument \'factory\' must not be null.";
         throw new IllegalArgumentException(var4);
      } else if(this._handlerFactoryList == null) {
         return false;
      } else if(!this._handlerFactoryList.removeElement(factory)) {
         return false;
      } else {
         this._handlerFactoryMap.clear();

         for(int i = 0; i < this._handlerFactoryList.size(); ++i) {
            FieldHandlerFactory tmp = (FieldHandlerFactory)this._handlerFactoryList.elementAt(i);
            this.registerHandlerFactory(tmp);
         }

         return true;
      }
   }

   public void setWrapCollections(boolean wrapCollections) {
      this._wrapCollectionsInContainer = wrapCollections;
   }

   public static boolean introspected(XMLClassDescriptor descriptor) {
      return descriptor instanceof IntrospectedXMLClassDescriptor;
   }

   public static boolean marshallable(Class type) {
      if(type != Void.class && type != Class.class) {
         if((!type.isInterface() || type == Object.class) && !isPrimitive(type) && !type.isArray()) {
            try {
               type.getConstructor(EMPTY_CLASS_ARGS);
            } catch (NoSuchMethodException var2) {
               return CoreDescriptors.getDescriptor(type) != null;
            }
         }

         return true;
      } else {
         return false;
      }
   }

   public void setNaming(XMLNaming naming) {
      if(naming == null) {
         this._xmlNaming = _defaultNaming;
      } else {
         this._xmlNaming = naming;
      }

   }

   public void setPrimitiveNodeType(NodeType nodeType) {
      if(nodeType == NodeType.Element) {
         this._primitiveNodeType = nodeType;
      } else {
         this._primitiveNodeType = NodeType.Attribute;
      }

   }

   public void setSaveMapKeys(boolean saveMapKeys) {
      this._saveMapKeys = saveMapKeys;
   }

   public static String toJavaName(String name, boolean upperFirst) {
      int size = name.length();
      char[] ncChars = name.toCharArray();
      int next = 0;
      boolean uppercase = upperFirst;

      for(int i = 0; i < size; ++i) {
         char ch = ncChars[i];
         switch(ch) {
         case '-':
         case ':':
            uppercase = true;
            break;
         default:
            if(uppercase) {
               ncChars[next] = Character.toUpperCase(ch);
               uppercase = false;
            } else {
               ncChars[next] = ch;
            }

            ++next;
         }
      }

      return new String(ncChars, 0, next);
   }

   private XMLFieldDescriptorImpl createFieldDescriptor(Class type, String fieldName, String xmlName) {
      XMLFieldDescriptorImpl fieldDesc = new XMLFieldDescriptorImpl(type, fieldName, xmlName, (NodeType)null);
      if(type.isArray()) {
         fieldDesc.setNodeType(NodeType.Element);
      } else if(type.isPrimitive()) {
         fieldDesc.setNodeType(this._primitiveNodeType);
      } else {
         fieldDesc.setNodeType(NodeType.Element);
      }

      if(type == Object.class) {
         fieldDesc.setMatches(xmlName + " *");
      }

      return fieldDesc;
   }

   private FieldHandlerFactory getHandlerFactory(Class type) {
      if(this._handlerFactoryMap != null) {
         for(Class tmp = type; tmp != null; tmp = tmp.getSuperclass()) {
            Object obj = this._handlerFactoryMap.get(tmp);
            if(obj != null) {
               return (FieldHandlerFactory)obj;
            }
         }
      }

      return DEFAULT_HANDLER_FACTORY.isSupportedType(type)?DEFAULT_HANDLER_FACTORY:null;
   }

   private void registerHandlerFactory(FieldHandlerFactory factory) {
      if(this._handlerFactoryMap == null) {
         this._handlerFactoryMap = new Hashtable();
      }

      Class[] types = factory.getSupportedTypes();

      for(int i = 0; i < types.length; ++i) {
         this._handlerFactoryMap.put(types[i], factory);
      }

   }

   public static boolean isCollection(Class clazz) {
      if(clazz.isArray()) {
         return true;
      } else {
         for(int i = 0; i < COLLECTIONS.length; ++i) {
            if(clazz == COLLECTIONS[i] || COLLECTIONS[i].isAssignableFrom(clazz)) {
               return true;
            }
         }

         return false;
      }
   }

   public static boolean isMapCollection(Class clazz) {
      if(clazz.isArray()) {
         return false;
      } else {
         for(int i = 0; i < COLLECTIONS.length; ++i) {
            if(clazz == COLLECTIONS[i] || COLLECTIONS[i].isAssignableFrom(clazz)) {
               if(COLLECTIONS[i] == Hashtable.class) {
                  return true;
               }

               if(COLLECTIONS[i].getName().equals("java.util.Map")) {
                  return true;
               }
            }
         }

         return false;
      }
   }

   private static boolean isDescriptable(Class type) {
      if(type != Void.class && type != Class.class) {
         float javaVersion = Float.valueOf(System.getProperty("java.specification.version")).floatValue();
         if((double)javaVersion >= 1.5D) {
            try {
               Boolean e = ReflectionUtil.isEnumViaReflection(type);
               if(e.booleanValue()) {
                  return true;
               }
            } catch (Exception var3) {
               ;
            }
         }

         if(!type.isInterface() && type != Object.class && !isPrimitive(type) && !type.isArray()) {
            try {
               type.getConstructor(EMPTY_CLASS_ARGS);
            } catch (NoSuchMethodException var4) {
               return CoreDescriptors.getDescriptor(type) != null;
            }
         }

         return true;
      } else {
         return false;
      }
   }

   private static boolean isPrimitive(Class type) {
      if(type.isPrimitive()) {
         return true;
      } else if(type != Boolean.class && type != Character.class) {
         Class superClass = type.getSuperclass();
         return superClass == Number.class?true:(superClass != null?superClass.getName().equals("java.lang.Enum"):false);
      } else {
         return true;
      }
   }

   private static Class[] loadCollections() {
      Vector collections = new Vector(6);
      collections.addElement(Vector.class);
      collections.addElement(Enumeration.class);
      collections.addElement(Hashtable.class);
      ClassLoader loader = Vector.class.getClassLoader();
      Class clazz = null;

      try {
         if(loader != null) {
            clazz = loader.loadClass("java.util.List");
         } else {
            clazz = Class.forName("java.util.List");
         }
      } catch (ClassNotFoundException var5) {
         ;
      }

      if(clazz != null) {
         collections.addElement(clazz);
         clazz = null;

         try {
            if(loader != null) {
               clazz = loader.loadClass("java.util.Map");
            } else {
               clazz = Class.forName("java.util.Map");
            }

            if(clazz != null) {
               collections.addElement(clazz);
            }

            if(loader != null) {
               clazz = loader.loadClass("java.util.Set");
            } else {
               clazz = Class.forName("java.util.Set");
            }

            if(clazz != null) {
               collections.addElement(clazz);
            }
         } catch (ClassNotFoundException var4) {
            ;
         }
      }

      Class[] classes = new Class[collections.size()];
      collections.copyInto(classes);
      return classes;
   }

   class MethodSet {
      Method _add = null;
      Method _create = null;
      Method _get = null;
      Method _set = null;
      String _fieldName = null;

      MethodSet(String fieldName) {
         this._fieldName = fieldName;
      }
   }

   class IdentityConvertor implements TypeConvertor {
      public Object convert(Object object) {
         return object;
      }
   }
}
Page generated: Oct 19, 2017 2:35:18 PM