Package org.eclipse.persistence.jpa.jpql.tools.spi.java

Source Code of org.eclipse.persistence.jpa.jpql.tools.spi.java.JavaTypeRepository

/*******************************************************************************
* Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Oracle - initial API and implementation
*
******************************************************************************/
package org.eclipse.persistence.jpa.jpql.tools.spi.java;

import java.util.HashMap;
import java.util.Map;
import org.eclipse.persistence.jpa.jpql.tools.TypeHelper;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;
import org.eclipse.persistence.jpa.jpql.tools.spi.ITypeRepository;

/**
* The concrete implementation of {@link ITypeRepository} that is wrapping the Java class loader.
*
* @version 2.4
* @since 2.3
* @author Pascal Filion
*/
@SuppressWarnings("nls")
public class JavaTypeRepository implements ITypeRepository {

  /**
   * The repository used to access the application's classes.
   */
  private final ClassLoader classLoader;

  /**
   * The helper that gives access to the most common {@link IType types}.
   */
  private TypeHelper typeHelper;

  /**
   * The types that have been cached for faster access.
   */
  private final Map<String, JavaType> types;

  /**
   * The {@link IType} that represents a unresolvable or simply an unknown type, which is created
   * when {@link #getType(String)} is invoked with {@link IType#UNRESOLVABLE_TYPE}.
   */
  private JavaType unresolvableType;

  /**
   * Creates a new <code>JavaTypeRepository</code>.
   *
   * @param classLoader The repository used to access the application's classes
   */
  public JavaTypeRepository(ClassLoader classLoader) {
    super();
    this.classLoader = classLoader;
    this.types       = new HashMap<String, JavaType>();
  }

  /**
   * Retrieves the Java type for the given type name, which has to be the fully qualified type name.
   *
   * @param typeName The fully qualified type name
   * @return The Java type if it could be retrieved; <code>null</code> otherwise
   */
  protected Class<?> attemptLoadType(String typeName) {

    if (typeName.equals("boolean")) return Boolean  .TYPE;
    if (typeName.equals("byte"))    return Byte     .TYPE;
    if (typeName.equals("char"))    return Character.TYPE;
    if (typeName.equals("double"))  return Double   .TYPE;
    if (typeName.equals("float"))   return Float    .TYPE;
    if (typeName.equals("int"))     return Integer  .TYPE;
    if (typeName.equals("long"))    return Long     .TYPE;
    if (typeName.equals("short"))   return Short    .TYPE;

    try {
      return classLoader.loadClass(typeName);
    }
    catch (ClassNotFoundException e) {
      return null;
    }
  }

  protected JavaType buildType(Class<?> javaType) {
    JavaType type = new JavaType(this, javaType);
    types.put(javaType.getName(), type);
    return type;
  }

  protected JavaType buildType(String typeName) {
    return new JavaType(this, typeName);
  }

  /**
   * Returns the {@link ClassLoader} that is used to load Java classes.
   *
   * @return The {@link ClassLoader} that is used to load Java classes
   */
  public ClassLoader getClassLoader() {
    return classLoader;
  }

  /**
   * {@inheritDoc}
   */
  public IType getEnumType(String enumTypeName) {

    // Get the position of the last dot so we can remove the constant
    int lastDotIndex = enumTypeName.lastIndexOf(".");

    if (lastDotIndex == -1) {
      return null;
    }

    // Retrieve the fully qualified enum type name
    String typeName = enumTypeName.substring(0, lastDotIndex);

    // Attempt to load the enum type
    IType type = loadTypeImp(typeName);
    return type.isEnum() ? type : null;
  }

  /**
   * {@inheritDoc}
   */
  public JavaType getType(Class<?> javaClass) {
    return getType(javaClass.getName());
  }

  /**
   * {@inheritDoc}
   */
  public JavaType getType(String typeName) {

    if (typeName == IType.UNRESOLVABLE_TYPE) {
      return unresolvableType();
    }

    if (typeName.charAt(0) == '[') {
      return loadArrayType(typeName);
    }

    return loadTypeImp(typeName);
  }

  /**
   * {@inheritDoc}
   */
  public TypeHelper getTypeHelper() {
    if (typeHelper == null) {
      typeHelper = new TypeHelper(this);
    }
    return typeHelper;
  }

  protected JavaType loadArrayType(String typeName) {

    JavaType type = types.get(typeName);

    if (type == null) {
      try {
        type = new JavaType(this, Class.forName(typeName));
      }
      catch (ClassNotFoundException f) {
        type = new JavaType(this, typeName);
      }
      types.put(typeName, type);
    }

    return type;
  }

  protected JavaType loadInnerType(String typeName) {

    int index = typeName.lastIndexOf(".");

    if (index == -1) {
      return null;
    }

    StringBuilder sb = new StringBuilder();
    sb.append(typeName.substring(0, index));
    sb.append("$");
    sb.append(typeName.substring(index + 1, typeName.length()));
    typeName = sb.toString();

    return loadTypeImp(typeName);
  }

  protected JavaType loadTypeImp(String typeName) {

    JavaType type = types.get(typeName);

    // The type was already cached, simply return it
    if (type != null) {
      return type;
    }

    // Attempt to load the Java type
    Class<?> javaType = attemptLoadType(typeName);

    // A Java type exists, return it
    if (javaType != null) {
      return buildType(javaType);
    }

    // Now try with a possible inner type
    type = loadInnerType(typeName);

    if (type == null) {
      type = buildType(typeName);
    }

    return type;
  }

  protected JavaType unresolvableType() {
    if (unresolvableType == null) {
      unresolvableType = new JavaType(this, IType.UNRESOLVABLE_TYPE);
    }
    return unresolvableType;
  }
}
TOP

Related Classes of org.eclipse.persistence.jpa.jpql.tools.spi.java.JavaTypeRepository

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.