/*
 * Copyright (c) 2011, 2020 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Rick Barkhouse - 2.2 - Initial implementation
package org.eclipse.persistence.jaxb.javamodel.oxm;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import jakarta.xml.bind.JAXBElement;

import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.compiler.XMLProcessor;
import org.eclipse.persistence.jaxb.javamodel.JavaAnnotation;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaClassInstanceOf;
import org.eclipse.persistence.jaxb.javamodel.JavaConstructor;
import org.eclipse.persistence.jaxb.javamodel.JavaField;
import org.eclipse.persistence.jaxb.javamodel.JavaMethod;
import org.eclipse.persistence.jaxb.javamodel.JavaModel;
import org.eclipse.persistence.jaxb.javamodel.JavaPackage;
import org.eclipse.persistence.jaxb.xmlmodel.JavaAttribute;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAnyAttribute;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAnyElement;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAttribute;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElement;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementRef;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElements;
import org.eclipse.persistence.jaxb.xmlmodel.XmlInverseReference;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlValue;

/**
 * INTERNAL:
 * <p>
 * <b>Purpose:</b> <code>JavaClass</code> implementation wrapping MOXy's <code>xmlmodel.JavaType</code>.
 * Used when bootstrapping a <code>DynamicJAXBContext</code> from XML Bindings.
 * </p>
 *
 * <p>
 * <b>Responsibilities:</b>
 * </p>
 * <ul>
 *    <li>Provide Class information from the underlying <code>JavaType</code>.</li>
 * </ul>
 *
 * @since EclipseLink 2.2
 *
 * @see org.eclipse.persistence.jaxb.javamodel.JavaClass
 * @see org.eclipse.persistence.jaxb.xmlmodel.JavaType
 */
public class OXMJavaClassImpl implements JavaClass {

    private JavaType javaType;
    private String javaName;
    private List<String> enumValues;
    private JavaModel javaModel;

    /**
     * Construct a new instance of <code>OXMJavaClassImpl</code>.
     *
     * @param aJavaType - the XJC <code>JavaType</code> to be wrapped.
     */
    public OXMJavaClassImpl(JavaType aJavaType) {
        this.javaType = aJavaType;
    }

    /**
     * Construct a new instance of <code>OXMJavaClassImpl</code>.
     *
     * @param aJavaTypeName - the name of the JavaType to create.
     */
    public OXMJavaClassImpl(String aJavaTypeName) {
        this.javaName = aJavaTypeName;
    }

    /**
     * Construct a new instance of <code>OXMJavaClassImpl</code>
     * representing a Java <code>enum</code>.
     *
     * @param aJavaTypeName - the name of the JavaType to create.
     * @param enumValues - the list of values for this <code>enum</code>.
     */
    public OXMJavaClassImpl(String aJavaTypeName, List<String> enumValues) {
        this.javaName = aJavaTypeName;
        this.enumValues = enumValues;
    }

    // ========================================================================

    /**
     * Return the "actual" type from a parameterized type.  For example, if this
     * <code>JavaClass</code> represents <code>List&lt;Employee</code>, this method will return the
     * <code>Employee</code> <code>JavaClass</code>.
     *
     * @return a <code>Collection</code> containing the actual type's <code>JavaClass</code>.
     */
    @Override
    public Collection<JavaClass> getActualTypeArguments() {
        Object jType = null;
        if (this.javaType != null) {
            jType = this.javaType;
        } else {
            try {
                Class<?> jTypeClass = PrivilegedAccessHelper.getClassForName(this.javaName);
                jType = PrivilegedAccessHelper.newInstanceFromClass(jTypeClass);
            } catch (Exception e) {
                return new ArrayList<JavaClass>();
            }
        }

        ArrayList<JavaClass> argCollection = new ArrayList<JavaClass>();
        if (jType instanceof ParameterizedType) {
            ParameterizedType pType = (ParameterizedType) jType;
            Type[] params = pType.getActualTypeArguments();
            for (Type type : params) {
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    argCollection.add(this.javaModel.getClass(pt.getRawType().getClass()));
                } else if (type instanceof WildcardType) {
                    Type[] upperTypes = ((WildcardType) type).getUpperBounds();
                    if (upperTypes.length >0) {
                        Type upperType = upperTypes[0];
                        if (upperType instanceof Class<?>) {
                            argCollection.add(this.javaModel.getClass(upperType.getClass()));
                        }
                    }
                } else if (type instanceof Class<?>) {
                    argCollection.add(this.javaModel.getClass(type.getClass()));
                } else if (type instanceof GenericArrayType) {
                    Class<?> genericTypeClass = (Class<?>) ((GenericArrayType) type).getGenericComponentType();
                    genericTypeClass = java.lang.reflect.Array.newInstance(genericTypeClass, 0).getClass();
                    argCollection.add(this.javaModel.getClass(genericTypeClass.getClass()));
                }
            }
        }
        return argCollection;
    }

    /**
     * If this <code>JavaClass</code> is an array type, return the type of the
     * array components.
     *
     * @return always returns <code>null</code>, as <code>JavaTypes</code> do not represent arrays.
     */
    @Override
    public JavaClass getComponentType() {
        return null;
    }

    /**
     * Return the <code>JavaConstructor</code> for this <code>JavaClass</code> that has the
     * provided parameter types.
     *
     * @param parameterTypes the parameter list used to identify the constructor.
     *
     * @return the <code>JavaConstructor</code> with the signature matching parameterTypes.
     */
    @Override
    public JavaConstructor getConstructor(JavaClass[] parameterTypes) {
        return new OXMJavaConstructorImpl(this);
    }

    /**
     * Return all of the <code>JavaConstructors</code> for this JavaClass.
     *
     * @return A <code>Collection</code> containing this <code>JavaClass'</code> <code>JavaConstructors</code>.
     */
    @Override
    public Collection<JavaConstructor> getConstructors() {
        ArrayList<JavaConstructor> constructors = new ArrayList<JavaConstructor>(1);
        constructors.add(new OXMJavaConstructorImpl(this));
        return constructors;
    }

    /**
     * Return this <code>JavaClass'</code> inner classes.
     *
     * @return always returns an empty <code>ArrayList</code> as <code>JavaTypes</code> do not represent inner classes.
     */
    @Override
    public Collection<JavaClass> getDeclaredClasses() {
        return new ArrayList<JavaClass>();
    }

    /**
     * Return the declared <code>JavaConstructor</code> for this <code>JavaClass</code>.
     *
     * @return the <code>JavaConstructor</code> for this <code>JavaClass</code>.
     */
    @Override
    public JavaConstructor getDeclaredConstructor(JavaClass[] parameterTypes) {
        return new OXMJavaConstructorImpl(this);
    }

    /**
     * Return all of the declared <code>JavaConstructors</code> for this <code>JavaClass</code>.
     *
     * @return A <code>Collection</code> containing this <code>JavaClass'</code> <code>JavaConstructors</code>.
     */
    @Override
    public Collection<JavaConstructor> getDeclaredConstructors() {
        ArrayList<JavaConstructor> constructors = new ArrayList<JavaConstructor>(1);
        constructors.add(new OXMJavaConstructorImpl(this));
        return constructors;
    }

    /**
     * Return the declared <code>JavaField</code> for this <code>JavaClass</code>, identified
     * by <code>fieldName</code>.
     *
     * @param name the name of the <code>JavaField</code> to return.
     *
     * @return the <code>JavaField</code> named <code>fieldName</code> from this <code>JavaClass</code>.
     */
    @Override
    public JavaField getDeclaredField(String name) {
        Collection<JavaField> allFields = getDeclaredFields();

        for (Iterator<JavaField> iterator = allFields.iterator(); iterator.hasNext();) {
            JavaField field = iterator.next();
            if (field.getName().equals(name)) {
                return field;
            }
        }

        return null;
    }

    /**
     * Return all of the declared <code>JavaFields</code> for this <code>JavaClass</code>.
     *
     * @return A <code>Collection</code> containing this <code>JavaClass'</code> <code>JavaFields</code>.
     */
    @Override
    public Collection<JavaField> getDeclaredFields() {
        List<JavaField> fieldsToReturn = new ArrayList<JavaField>();

        if (this.enumValues != null) {
            for (Iterator<String> iterator = this.enumValues.iterator(); iterator.hasNext();) {
                fieldsToReturn.add(new OXMJavaFieldImpl(iterator.next(), JAVA_LANG_OBJECT, this));
            }
        } else {
            JavaAttributes javaAttributes = this.javaType.getJavaAttributes();
            if(null != javaAttributes) {
                List<JAXBElement<? extends JavaAttribute>> fields = javaAttributes.getJavaAttribute();

                for (Iterator<JAXBElement<? extends JavaAttribute>> iterator = fields.iterator(); iterator.hasNext();) {
                    JAXBElement<? extends JavaAttribute> jaxbElement = iterator.next();

                    JavaAttribute att = jaxbElement.getValue();

                    if (att instanceof XmlElement) {
                        XmlElement xme = (XmlElement) att;
                        String fieldName = xme.getJavaAttribute();
                        String fieldType = xme.getType();
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlElements) {
                        XmlElements xmes = (XmlElements) att;
                        String fieldName = xmes.getJavaAttribute();
                        String fieldType = JAVA_LANG_OBJECT;
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlElementRef) {
                        XmlElementRef xmer = (XmlElementRef) att;
                        String fieldName = xmer.getJavaAttribute();
                        String fieldType = xmer.getType();
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlAttribute) {
                        XmlAttribute xma = (XmlAttribute) att;
                        String fieldName = xma.getJavaAttribute();
                        String fieldType = xma.getType();
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlValue) {
                        XmlValue xmv = (XmlValue) att;
                        String fieldName = xmv.getJavaAttribute();
                        String fieldType = xmv.getType();
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlAnyElement) {
                        XmlAnyElement xmae = (XmlAnyElement) att;
                        String fieldName = xmae.getJavaAttribute();
                        String fieldType = JAVA_LANG_OBJECT;
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlAnyAttribute) {
                        XmlAnyAttribute xmaa = (XmlAnyAttribute) att;
                        String fieldName = xmaa.getJavaAttribute();
                        String fieldType = JAVA_UTIL_MAP;
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlJoinNodes) {
                        XmlJoinNodes xmjn = (XmlJoinNodes) att;
                        String fieldName = xmjn.getJavaAttribute();
                        String fieldType = xmjn.getType();
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    } else if (att instanceof XmlInverseReference) {
                        XmlInverseReference xmir = (XmlInverseReference) att;
                        String fieldName = xmir.getJavaAttribute();
                        String fieldType = xmir.getType();
                        fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
                    }
                }
            }
        }

        return fieldsToReturn;
    }

    /**
     * Return the declared <code>JavaMethod</code> for this <code>JavaClass</code>,
     * identified by <code>name</code>, with the signature matching <code>args</code>.
     *
     * @param name the name of the <code>JavaMethod</code> to return.
     * @param args the parameter list used to identify the method.
     *
     * @return always returns <code>null</code>, as <code>JavaTypes</code> do not have methods.
     */
    @Override
    public JavaMethod getDeclaredMethod(String name, JavaClass[] args) {
        return null;
    }

    /**
     * Return all of the declared <code>JavaMethods</code> for this <code>JavaClass</code>.
     *
     * @return always returns an empty <code>ArrayList</code>, as <code>JavaTypes</code> do not have methods.
     */
    @Override
    public Collection<JavaMethod> getDeclaredMethods() {
        return new ArrayList<JavaMethod>();
    }

    /**
     * Return the <code>JavaMethod</code> for this <code>JavaClass</code>,
     * identified by <code>name</code>, with the signature matching <code>args</code>.
     *
     * @param name the name of the <code>JavaMethod</code> to return.
     * @param args the parameter list used to identify the method.
     *
     * @return always returns <code>null</code>, as <code>JavaTypes</code> do not have methods.
     */
    @Override
    public JavaMethod getMethod(String name, JavaClass[] args) {
        return null;
    }

    /**
     * Return all of the <code>JavaMethods</code> for this <code>JavaClass</code>.
     *
     * @return always returns an empty <code>ArrayList</code>, as <code>JavaTypes</code> do not have methods.
     */
    @Override
    public Collection<JavaMethod> getMethods() {
        return new ArrayList<JavaMethod>();
    }

    /**
     * Returns the Java language modifiers for this <code>JavaClass</code>, encoded in an integer.
     *
     * @return always returns <code>0</code> as <code>JavaTypes</code> do not have modifiers.
     *
     * @see java.lang.reflect.Modifier
     */
    @Override
    public int getModifiers() {
        return 0;
    }

    /**
     * Returns the name of this <code>JavaClass</code>.
     *
     * @return the <code>String</code> name of this <code>JavaClass</code>.
     */
    @Override
    public String getName() {
        if (this.javaType != null) {
            return this.javaType.getName();
        }
        return this.javaName;
    }

    /**
     * Returns the <code>JavaPackage</code> that this <code>JavaClass</code> belongs to.
     *
     * @return the <code>JavaPackage</code> of this <code>JavaClass</code>.
     */
    @Override
    public JavaPackage getPackage() {
        return new OXMJavaPackageImpl(getPackageName());
    }

    /**
     * Returns the package name of this <code>JavaClass</code>.
     *
     * @return the <code>String</code> name of this <code>JavaClass'</code> <code>JavaPackage</code>.
     */
    @Override
    public String getPackageName() {
        int lastDotIndex = getQualifiedName().lastIndexOf('.');
        if (lastDotIndex == -1) {
            return EMPTY_STRING;
        }

        return getQualifiedName().substring(0, lastDotIndex);
    }

    /**
     * Returns the fully-qualified name of this <code>JavaClass</code>.
     *
     * @return the <code>String</code> name of this <code>JavaClass</code>.
     */
    @Override
    public String getQualifiedName() {
        return getName();
    }

    /**
     * Returns the raw name of this <code>JavaClass</code>.  Array types will
     * have "[]" appended to the name.
     *
     * @return the <code>String</code> raw name of this <code>JavaClass</code>.
     */
    @Override
    public String getRawName() {
        return getName();
    }

    /**
     * Returns the super class of this <code>JavaClass</code>.
     *
     * @return <code>JavaClass</code> representing the super class of this <code>JavaClass</code>.
     */
    @Override
    public JavaClass getSuperclass() {
        if (this.javaModel == null) {
            return null;
        }
        if (this.javaType != null) {
            if (!(this.javaType.getSuperType().equals(XMLProcessor.DEFAULT))) {
                return this.javaModel.getClass(javaType.getSuperType());
            }
        }
        return this.javaModel.getClass(JAVA_LANG_OBJECT);
    }

    @Override
    public Type[] getGenericInterfaces() {
        return new Type[0];
    }

    @Override
    public Type getGenericSuperclass() {
        return null;
    }

    /**
     * Indicates if this <code>JavaClass</code> has actual type arguments, i.e. is a
     * parameterized type (for example, <code>List&lt;Employee</code>).
     *
     * @return always returns <code>false</code> as <code>JavaTypes</code> are not parameterized.
     */
    @Override
    public boolean hasActualTypeArguments() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is <code>abstract</code>.
     *
     * @return always returns <code>false</code> as <code>JavaTypes</code> are never <code>abstract</code>.
     */
    @Override
    public boolean isAbstract() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is an <code>Annotation</code>.
     *
     * @return always returns <code>false</code> as <code>JavaTypes</code> are never <code>Annotations</code>.
     */
    @Override
    public boolean isAnnotation() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is an Array type.
     *
     * @return always returns <code>false</code>, as <code>JavaTypes</code> do not represent arrays.
     */
    @Override
    public boolean isArray() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is either the same as, or is a superclass of,
     * the <code>javaClass</code> argument.
     *
     * @param arg0 the <code>Class</code> to test.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is assignable from
     *         <code>javaClass</code>, otherwise <code>false</code>.
     *
     * @see java.lang.Class#isAssignableFrom(Class)
     */
    @Override
    @SuppressWarnings("unchecked")
    public boolean isAssignableFrom(JavaClass arg0) {
        String thisJavaName = EMPTY_STRING;
        String argJavaName = arg0.getName();

        if (this.javaName != null) {
            thisJavaName = this.javaName;
        } else {
            thisJavaName = this.javaType.getName();
        }

        if (thisJavaName.startsWith(JAVA) && argJavaName.startsWith(JAVA)) {
            // Only try class lookup if this is a JDK class, because
            // we won't ever find classes for dynamically generated types.
            try {
                Class thisClass = PrivilegedAccessHelper.getClassForName(thisJavaName);
                Class argClass = PrivilegedAccessHelper.getClassForName(argJavaName);
                return thisClass.isAssignableFrom(argClass);
            } catch (Exception e) {
                return false;
            }
        } else {
            return thisJavaName.equals(argJavaName);
        }
    }

    /**
     * Indicates if this <code>JavaClass</code> is an <code>enum</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is an <code>enum</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isEnum() {
        return this.enumValues != null;
    }

    /**
     * Indicates if this <code>JavaClass</code> is <code>final</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is <code>final</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isFinal() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is an <code>interface</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is an <code>interface</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isInterface() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is an inner <code>Class</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is an inner <code>Class</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isMemberClass() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> represents a primitive type.
     *
     * @return <code>true</code> if this <code>JavaClass</code> represents a primitive type, otherwise <code>false</code>.
     */
    @Override
    public boolean isPrimitive() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is <code>private</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is <code>private</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isPrivate() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is <code>protected</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is <code>protected</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isProtected() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is <code>public</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is <code>public</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isPublic() {
        return false;
    }

    /**
     * Indicates if this <code>JavaClass</code> is <code>static</code>.
     *
     * @return <code>true</code> if this <code>JavaClass</code> is <code>static</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isStatic() {
        return false;
    }

    /**
     * Not supported.
     */
    @Override
    public boolean isSynthetic() {
        throw new UnsupportedOperationException("isSynthetic");
    }

    @Override
    public JavaClassInstanceOf instanceOf() {
        return JavaClassInstanceOf.OXM_JAVA_CLASS_IMPL;
    }

    /**
     * If this <code>JavaClass</code> is annotated with an <code>Annotation</code> matching <code>aClass</code>,
     * return its <code>JavaAnnotation</code> representation.
     *
     * @param aClass a <code>JavaClass</code> representing the <code>Annotation</code> to look for.
     *
     * @return always returns <code>null</code>, as <code>JavaTypes</code> do not have <code>Annotations</code>.
     */
    @Override
    public JavaAnnotation getAnnotation(JavaClass aClass) {
        return null;
    }

    /**
     * Return all of the <code>Annotations</code> for this <code>JavaClass</code>.
     *
     * @return always returns an empty <code>ArrayList</code>, as <code>JavaTypes</code> do not have <code>Annotations</code>.
     */
    @Override
    public Collection<JavaAnnotation> getAnnotations() {
        return new ArrayList<JavaAnnotation>();
    }

    /**
     * If this <code>JavaClass</code> declares an <code>Annotation</code> matching <code>aClass</code>,
     * return its <code>JavaAnnotation</code> representation.
     *
     * @param arg0 a <code>JavaClass</code> representing the <code>Annotation</code> to look for.
     *
     * @return always returns <code>null</code>, as <code>JavaTypes</code> do not have <code>Annotations</code>.
     */
    @Override
    public JavaAnnotation getDeclaredAnnotation(JavaClass arg0) {
        return null;
    }

    /**
     * Return all of the declared <code>Annotations</code> for this <code>JavaClass</code>.
     *
     * @return always returns an empty <code>ArrayList</code>, as <code>JavaTypes</code> do not have <code>Annotations</code>.
     */
    @Override
    public Collection<JavaAnnotation> getDeclaredAnnotations() {
        return new ArrayList<JavaAnnotation>();
    }

    /**
     * Set this <code>JavaClass'</code> <code>JavaModel</code>.
     *
     * @param model The <code>JavaModel</code> to set.
     */
    public void setJavaModel(JavaModel model) {
        this.javaModel = model;
    }

    /**
     * Get this <code>JavaClass'</code> <code>JavaModel</code>.
     *
     * @return The <code>JavaModel</code> associated with this <code>JavaClass</code>.
     */
    public JavaModel getJavaModel() {
        return this.javaModel;
    }

    // ========================================================================

    private static String EMPTY_STRING = "";
    private static String JAVA = "java";
    private static String DOT = ".";
    private static String JAVA_LANG_OBJECT = "java.lang.Object";
    private static String JAVA_UTIL_MAP = "java.util.Map";

}
