Package fr.imag.adele.apam.declarations.encoding.ipojo

Source Code of fr.imag.adele.apam.declarations.encoding.ipojo.InstrumentedClassMetadata

package fr.imag.adele.apam.declarations.encoding.ipojo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.Vector;

import org.apache.felix.ipojo.parser.FieldMetadata;
import org.apache.felix.ipojo.parser.MethodMetadata;
import org.apache.felix.ipojo.parser.PojoMetadata;

import fr.imag.adele.apam.declarations.instrumentation.InstrumentedClass;
import fr.imag.adele.apam.declarations.instrumentation.LoadedClassMetadata;

/**
* A utility class to obtain information about declared fields and methods.
*
* It tries to use java reflection metadata if available, otherwise it falls backs to use
* the iPojo metadata
*
* @author vega
*
*/
public class InstrumentedClassMetadata implements InstrumentedClass {

  /**
   * The iPojo generated metadata
   */
  private final PojoMetadata pojoMetadata;

  /**
   * The name of the instrumented class
   */
  private final String className;

  /**
   * The optional reflection information
   */
  private final LoadedClassMetadata loadedClass;

  public InstrumentedClassMetadata(String className, PojoMetadata pojoMetadata, Class<?> instrumentedCode) {
    this.className       = className;
    this.pojoMetadata     = pojoMetadata;
    this.loadedClass     = instrumentedCode != null ? new LoadedClassMetadata(instrumentedCode) : null;
  }

  /**
   * The list of supported collections for aggregate dependencies
   */
  private final static Class<?>[] supportedCollections = new Class<?>[] { Collection.class, List.class, Vector.class, Set.class };

  /**
   * The list of supported types for push message queues
   */
  private final static Class<?>[] supportedMessageQueues = new Class<?>[] { Queue.class, };

  /**
   * Utility method to get the associated box class name for a primitive type
   */

  private final static Map<String, Class<?>> box = new HashMap<String, Class<?>>();

  static {
    box.put(Boolean.TYPE.getName(), Boolean.class);
    box.put(Character.TYPE.getName(), Character.class);
    box.put(Byte.TYPE.getName(), Byte.class);
    box.put(Short.TYPE.getName(), Short.class);
    box.put(Integer.TYPE.getName(), Integer.class);
    box.put(Float.TYPE.getName(), Float.class);
    box.put(Long.TYPE.getName(), Long.class);
    box.put(Double.TYPE.getName(), Double.class);
  }

  /**
   * If the type of the specified field is one of the supported collections returns the type of the elements
   * in the collection, otherwise return null.
   *
   * May return {@link UNKNOWN_TYPE} if the type of the elements in the collection cannot be determined.
   */
  private static String getCollectionType(FieldMetadata field) {
    String fieldType = field.getFieldType();

    if (fieldType.endsWith("[]")) {
      int index = fieldType.indexOf('[');
      return boxed(fieldType.substring(0, index));
    }

    for (Class<?> supportedCollection : supportedCollections) {
      if (supportedCollection.getCanonicalName().equals(fieldType)) {
        return UNKNOWN_TYPE;
      }
    }

    return null;
  }


  private static String getMessageType(FieldMetadata field) {
    String fieldType = field.getFieldType();

    for (Class<?> supportedMessage : supportedMessageQueues) {
      if (supportedMessage.getCanonicalName().equals(fieldType)) {
        return UNKNOWN_TYPE;
      }
    }

    return null;
  }

  private static String boxed(String type) {
    Class<?> boxed = box.get(type);
    return boxed != null ? boxed.getCanonicalName() : type;
  }

  @Override
  public String getName() {
    return className;
  }

    @Override
  public String getDeclaredFieldType(String fieldName) throws NoSuchFieldException {

    /*
     * Try to get reflection information if available,.
     */
    String result = null;
    if (loadedClass != null) {
      try {
        result = loadedClass.getDeclaredFieldType(fieldName);
      } catch (Exception e) {
      }
    }

    if (result != null) {
      return result;
    }

    /*
     * Get iPojo metadata
     */
    FieldMetadata fieldIPojoMetadata = null;
    if ((pojoMetadata != null) && (pojoMetadata.getField(fieldName) != null)) {
      fieldIPojoMetadata = pojoMetadata.getField(fieldName);
    }

    if (fieldIPojoMetadata != null) {
      return fieldIPojoMetadata.getFieldType();
    }

    throw new NoSuchFieldException("unavailable field " + fieldName);

    }
   
  @Override
  public String getFieldType(String fieldName) throws NoSuchFieldException {

    /*
     * Try to get reflection information if available,.
     */
    String result = null;
    if (loadedClass != null) {
      try {
        result = loadedClass.getFieldType(fieldName);
      } catch (Exception e) {
      }
    }

    if (result != null) {
      return result;
    }

    /*
     * Get iPojo metadata
     */
    FieldMetadata fieldIPojoMetadata = null;
    if ((pojoMetadata != null) && (pojoMetadata.getField(fieldName) != null)) {
      fieldIPojoMetadata = pojoMetadata.getField(fieldName);
    }

    if (fieldIPojoMetadata != null) {

      /*
       * Verify if it is a collection
       */
      String collectionType = getCollectionType(fieldIPojoMetadata);
      if (collectionType != null) {
        return collectionType;
      }

      /*
       * Verify if it is a message
       */
      String messageType = getMessageType(fieldIPojoMetadata);
      if (messageType != null) {
        return messageType;
      }

      /*
       * Otherwise we just return the raw type
       */
      return fieldIPojoMetadata.getFieldType();
    }

    throw new NoSuchFieldException("unavailable field " + fieldName);

  }

  @Override
  public int getMethodParameterNumber(String methodName, boolean includeInherited) throws NoSuchMethodException {

    /*
     * Try to get reflection information if available,.
     */
    if (loadedClass != null) {
      try {
        return loadedClass.getMethodParameterNumber(methodName,includeInherited);
      } catch (Exception e) {
      }
    }

    /*
     * Try to use iPojo metadata
     */
    if (pojoMetadata != null) {
      for (MethodMetadata method : pojoMetadata.getMethods(methodName)) {
        return method.getMethodArguments().length;
      }
    }

    throw new NoSuchMethodException("unavailable metadata for method " + methodName);
  }

  @Override
  public String getMethodParameterType(String methodName, boolean includeInherited) throws NoSuchMethodException {

    /*
     * Try to get reflection information if available,.
     */
    String result = null;
    if (loadedClass != null) {
      try {
        result = loadedClass.getMethodParameterType(methodName,includeInherited);
      } catch (Exception e) {
      }
    }

    if (result != null) {
      return result;
    }

    /*
     * Try to use iPojo metadata
     */

    MethodMetadata methodIPojoMetadata = null;
    if (pojoMetadata != null) {
      for (MethodMetadata method : pojoMetadata.getMethods(methodName)) {

        String arguments[] = method.getMethodArguments();
        boolean match = (1 == arguments.length);
        if (match) {
          methodIPojoMetadata = method;
        }
      }
    }


    if (methodIPojoMetadata != null) {
      return boxed(methodIPojoMetadata.getMethodArguments()[0]);
    }

    throw new NoSuchMethodException("unavailable metadata for method " + methodName);

  }

  @Override
  public String[] getMethodParameterTypes(String methodName, boolean includeInherited) throws NoSuchMethodException {

    /*
     * Try to get reflection information if available,.
     */

    String[] result = null;
    if (loadedClass != null) {
      try {
        result = loadedClass.getMethodParameterTypes(methodName,includeInherited);
      } catch (Exception e) {
      }
    }

    if (result != null) {
      return result;
    }
   
    /*
     * Try to use iPojo metadata
     */
   
    List<String> signature = new ArrayList<String>();

    if (pojoMetadata != null) {
      for (MethodMetadata method : pojoMetadata.getMethods(methodName)) {

        for (String argument : method.getMethodArguments()) {
          signature.add(boxed(argument));
        }

        return signature.toArray(new String[0]);
      }
    }

    throw new NoSuchMethodException("unavailable metadata for method " + methodName);
  }

  @Override
  public String getMethodReturnType(String methodName, String methodSignature, boolean includeInherited) throws NoSuchMethodException {

    /*
     * Try to get reflection information if available,.
     */

    String result = null;
    if (loadedClass != null) {
      try {
        result = loadedClass.getMethodReturnType(methodName,methodSignature,includeInherited);
      } catch (Exception e) {
      }
    }

    if (result != null) {
      return result;
    }

    /*
     * Try to use iPojo metadata
     */
   
    MethodMetadata methodIPojoMetadata = null;
    if (pojoMetadata != null) {
      for (MethodMetadata method : pojoMetadata.getMethods(methodName)) {

        if (methodSignature == null) {
          methodIPojoMetadata = method;
          break;
        }

        String signature[] = methodSignature.split(",");
        String arguments[] = method.getMethodArguments();
        boolean match = (signature.length == arguments.length);

        for (int i = 0; match && i < signature.length; i++) {
          if (!signature[i].equals(arguments[i])) {
            match = false;
          }
        }

        if (match) {
          methodIPojoMetadata = method;
          break;
        }
      }
    }

    if (methodIPojoMetadata != null) {
      return boxed(methodIPojoMetadata.getMethodReturn());
    }

    throw new NoSuchMethodException("unavailable metadata for method " + methodName + "(" + methodSignature != null ? methodSignature : "" + ")");

  }

  @Override
  public boolean isCollectionField(String fieldName) throws NoSuchFieldException {

    /*
     * Try to get reflection information if available,.
     */

    if (loadedClass != null) {
      try {
        return loadedClass.isCollectionField(fieldName);
      } catch (Exception e) {
      }
    }
   
    /*
     * Get iPojo metadata
     */
    FieldMetadata fieldIPojoMetadata = null;
    if ((pojoMetadata != null) && (pojoMetadata.getField(fieldName) != null)) {
      fieldIPojoMetadata = pojoMetadata.getField(fieldName);
    }

    if (fieldIPojoMetadata != null) {
      return getCollectionType(fieldIPojoMetadata) != null;
    }

    throw new NoSuchFieldException("unavailable metadata for field " + fieldName);
  }

  @Override
  public boolean isMessageQueueField(String fieldName) throws NoSuchFieldException {
    /*
     * Try to get reflection information if available,.
     */

    if (loadedClass != null) {
      try {
        return loadedClass.isMessageQueueField(fieldName);
      } catch (Exception e) {
      }
    }

    /*
     * Get iPojo metadata
     */
    FieldMetadata fieldIPojoMetadata = null;
    if ((pojoMetadata != null) && (pojoMetadata.getField(fieldName) != null)) {
      fieldIPojoMetadata = pojoMetadata.getField(fieldName);
    }

    if (fieldIPojoMetadata != null) {
      return getMessageType(fieldIPojoMetadata) != null;
    }

    throw new NoSuchFieldException("unavailable metadata for field " + fieldName);
  }
}
TOP

Related Classes of fr.imag.adele.apam.declarations.encoding.ipojo.InstrumentedClassMetadata

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.