Package gap.service

Source Code of gap.service.Classes

/*
* Gap Data
* Copyright (C) 2009 John Pritchard
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package gap.service;

import gap.Primitive;
import gap.data.HasName;
import gap.data.Kind;
import gap.data.TableClass;
import gap.service.od.ClassDescriptor;
import gap.service.od.FieldDescriptor;
import gap.service.od.ImportDescriptor;
import gap.service.od.PackageDescriptor;
import gap.service.od.ODStateException;
import gap.util.ClassName;

import alto.io.u.Find;

import com.google.appengine.api.datastore.DataTypeUtils;

import java.io.File;
import java.util.StringTokenizer;

/**
* Class descriptors service.  A class descriptor describes a data
* store type.  This code is common between odlc and runtime
* requirements for class descriptor service.
*/
public class Classes {

    private final static lxl.Map<ClassName,jauk.Resource> R = new lxl.Map<ClassName,jauk.Resource>();

    private final static lxl.Map<ClassName,ClassDescriptor> C = new lxl.Map<ClassName,ClassDescriptor>();

    /**
     * Qualified and Unqualified names of table classes with short descriptors
     */
    private final static lxl.Map<ClassName,ClassDescriptor> T = new lxl.Map<ClassName,ClassDescriptor>();

    public final static Iterable<jauk.Resource> Resources(){
        return R.values();
    }
    public final static Iterable<ClassDescriptor> Classes(){
        return C.values();
    }


    /**
     * Permit a field to notify the compilation process that a type
     * name has been marked as a big table class.  This permits
     * interface types to be handled as table classes when declared as
     * <code>"*table"</code> fields within an ODL class.
     *
     * @param pkg Package descriptor for class
     * @param clas Incomplete class has not yet stored its package contructor internally
     * @param field Field of class finalizing its contruction
     */
    public final static void TouchTableClass(PackageDescriptor pkg, ClassDescriptor clas, FieldDescriptor field)
        throws java.io.IOException, gap.odl.Syntax
    {
        String packageName = Classes.PackageName(pkg);
        String typeName = Classes.ToString(field.getType());
        lxl.List<ImportDescriptor> imports = Classes.ImportsFor(clas);
        String cleanTypeName = CleanTypeName(typeName);

        if (null == Primitive.For(cleanTypeName) &&
            null == gap.data.List.Type.For(cleanTypeName) &&
            null == gap.data.Map.Type.For(cleanTypeName))
        {
            /*
             * Indirect resolution
             */
            for (ImportDescriptor imp : imports){
                String classname = ClassNameIn(cleanTypeName,imp);
                if (null != classname){
                    ClassName className = new ClassName(classname);
                    TouchTableClass(className);
                    return;
                }
            }
            /*
             * Direct resolution
             */
            ClassName className = new ClassName(cleanTypeName);
            if (className.qualified){

                TouchTableClass(className);
            }
            else {
                className = new ClassName(packageName+'.'+cleanTypeName);

                TouchTableClass(className);
            }
        }
    }
    public final static void TouchTableClass(ClassName name)
        throws java.io.IOException, gap.odl.Syntax
    {
        ClassDescriptor shortCd = new gap.util.ClassNameDescriptor(name);

        T.put(name, shortCd);

        if (name.qualified){

            T.put(new ClassName(name.unqualified), shortCd);
        }
    }
    public final static ClassDescriptor For(ClassName name)
        throws java.io.IOException, gap.odl.Syntax
    {
        ClassDescriptor cd;
        synchronized(C){
            cd = C.get(name);
        }
        if (null == cd){
            jauk.Resource resource = R.get(name);
            if (null != resource){
                gap.odl.Reader rdr = new gap.odl.Reader(resource);
                try {
                    cd = (new gap.odl.Class(rdr));
                }
                finally {
                    rdr.close();
                }
                synchronized(C){
                    C.put(name,cd);
                }
            }
        }
        if (null == cd){
            synchronized(T){
                cd = T.get(name);
            }
        }
        return cd;
    }
    public final static ClassDescriptor For(File file)
        throws java.io.IOException, gap.odl.Syntax
    {
        jauk.Resource resource = new jauk.Resource(file);
        ClassName name = new ClassName(file);
        synchronized(R){
            R.put(name,resource);
        }
        ClassDescriptor cd;
        synchronized(C){
            cd = C.get(name);
        }
        if (null == cd){
            gap.odl.Reader rdr = new gap.odl.Reader(resource);
            try {
                cd = (new gap.odl.Class(rdr));
            }
            finally {
                rdr.close();
            }
            synchronized(C){
                C.put(name,cd);
            }
        }
        return cd;
    }
    public final static ClassDescriptor For(HasName named)
        throws java.io.IOException, gap.odl.Syntax
    {
        return Classes.For(named.getName());
    }
    public final static ClassDescriptor For(String name)
        throws java.io.IOException, gap.odl.Syntax
    {
        ClassName cn = new ClassName(name), ucn;
        if (cn.qualified)
            ucn = new ClassName(cn.unqualified);
        else
            ucn = cn;

        return Classes.For(ucn);
    }
    public final static ClassDescriptor For(Class<? extends TableClass> jclass)
        throws java.io.IOException, gap.odl.Syntax
    {
        if (null != jclass){
            String path = "odl/"+jclass.getName().replace('.','/')+".odl";
            return For(new File(path));
        }
        else
            throw new IllegalArgumentException();
    }
    public final static ClassDescriptor For(Object type)
        throws java.io.IOException, gap.odl.Syntax
    {
        if (type instanceof String)
            return For((String)type);
        else if (type instanceof ClassDescriptor)
            return (ClassDescriptor)type;
        else
            return null;
    }
    public final static ClassDescriptor ForData(String name)
        throws java.io.IOException, gap.odl.Syntax
    {
        if (null != name && name.endsWith("Data"))
            return Classes.For(name.substring(0,name.length()-4));
        else
            return null;

    }
    public final static ClassDescriptor ForServlet(String name)
        throws java.io.IOException, gap.odl.Syntax
    {
        if (null != name && name.endsWith("Servlet")){
            name = name.substring(0,name.length()-7);
            int idx = name.lastIndexOf('.');
            if (-1 != idx)
                name = name.substring(idx+1);
            return Classes.For(name);
        }
        else
            return null;
    }
    public final static PackageDescriptor PackageFor(ClassDescriptor gclass)
    {
        return PackageFor(gclass,null);
    }
    public final static PackageDescriptor PackageFor(ClassDescriptor gclass, PackageDescriptor scope){
        if (gclass instanceof ClassDescriptor.WithPackage){
            ClassDescriptor.WithPackage pclass = (ClassDescriptor.WithPackage)gclass;
            if (pclass.hasPackage())
                return pclass.getPackage();
        }
        return scope;
    }
    public final static PackageDescriptor PackageFor(Primitive gclass, Class pclass){
        if (null != pclass)
            return new gap.odl.Package(pclass);
        else
            return new gap.odl.Package(gclass.type);
    }
    public final static String GetPackageClassName(ClassDescriptor gclass){
        if (gclass instanceof ClassDescriptor.WithPackage){

            return ((ClassDescriptor.WithPackage)gclass).getPackageClassName();
        }
        else
            return gclass.getName();
    }
    public final static lxl.List<ImportDescriptor> ImportsFor(ClassDescriptor gclass)
    {
        if (gclass instanceof ClassDescriptor.WithImports){
            ClassDescriptor.WithImports iclass = (ClassDescriptor.WithImports)gclass;

            return iclass.getImports();
        }
        else
            throw new IllegalArgumentException();
    }
    public final static lxl.List<ImportDescriptor> ImportsFor(ClassDescriptor gclass,
                                                              lxl.List<ImportDescriptor> scope)
    {
        if (gclass instanceof ClassDescriptor.WithImports){
            ClassDescriptor.WithImports iclass = (ClassDescriptor.WithImports)gclass;
            if (iclass.hasImports())
                return iclass.getImports();
        }
        return scope;
    }
    public final static lxl.List<ImportDescriptor> ImportsFor(Primitive field,
                                                              ClassDescriptor definer,
                                                              lxl.List<ImportDescriptor> scope)
    {
        return ImportsFor(definer,scope);
    }
    /**
     * @param find Listing of odl files
     * @return Number of files found from listing
     */
    public final static int Resources(Find find){
        int count = 0;
        while (find.hasNext()){
            jauk.Resource file = new jauk.Resource(find.next());
            ClassName name = new ClassName(file);
            synchronized(R){
                R.put(name,file);
            }
            count += 1;
        }
        return count;
    }
    public final static String Camel(String string){
        if (null != string){
            int strlen = string.length();
            if (0 != strlen){
                if (1 != strlen)
                    return (string.substring(0,1).toUpperCase()+string.substring(1));
                else
                    return string.toUpperCase();
            }
            else
                throw new IllegalArgumentException();
        }
        else
            throw new IllegalArgumentException();
    }
    public final static String Decamel(String string){
        if (1 < string.length())
            return (string.substring(0,1).toLowerCase()+string.substring(1));
        else
            return string.toLowerCase();
    }
    public final static String ClassVersion(ClassDescriptor cd){
        if (cd instanceof ClassDescriptor.Version){
            ClassDescriptor.Version cv = (ClassDescriptor.Version)cd;
            if (cv.hasVersion()){
                return cv.getVersion().toString();
            }
        }
        return "1";
    }
    public final static String ClassKind(ClassDescriptor cd){
        if (cd instanceof ClassDescriptor.Kind){
            ClassDescriptor.Kind cdk = (ClassDescriptor.Kind)cd;
            if (cdk.hasKind())
                return cdk.getKind();
        }
        String definitionClassName = cd.getDefinitionClassName();
        if (null != definitionClassName){
            try {
                Class clas = null;
                try {
                    clas = Class.forName(definitionClassName,true,Thread.currentThread().getContextClassLoader());
                }
                catch (SecurityException retry){
                    clas = Class.forName(definitionClassName);
                }
                java.lang.reflect.Field fieldKind = clas.getField("KIND");
                return (String)fieldKind.get(null);
            }
            catch (Exception exc){
            }
        }
        return cd.getName();
    }
    public final static String ClassPath(ClassDescriptor cd){
        if (cd instanceof ClassDescriptor.Path){
            ClassDescriptor.Path cdp = (ClassDescriptor.Path)cd;
            if (cdp.hasPath())
                return cdp.getPath();
            else
                throw new ODStateException(cd,"OD Model requires 'path' field of class.");
        }
        else
            return null;
    }
    public final static String ClassSortBy(ClassDescriptor cd){
        if (cd instanceof ClassDescriptor.SortBy){
            ClassDescriptor.SortBy cdk = (ClassDescriptor.SortBy)cd;
            if (cdk.hasSortBy())
                return cdk.getSortBy();
        }
        String definitionClassName = cd.getDefinitionClassName();
        if (null != definitionClassName){
            try {
                Class clas = null;
                try {
                    clas = Class.forName(definitionClassName,true,Thread.currentThread().getContextClassLoader());
                }
                catch (SecurityException retry){
                    clas = Class.forName(definitionClassName);
                }
                return ClassSortBy(clas);
            }
            catch (Exception exc){
            }
        }
        return null;
    }
    public final static String ClassSortBy(Class<? extends gap.data.TableClass> table){
        if (null != table){
            try {
                java.lang.reflect.Field fieldDefaultSortBy = table.getField("DefaultSortBy");
                return (String)fieldDefaultSortBy.get(null);
            }
            catch (Exception exc){
            }
        }
        return null;
    }
    public final static String[] ClassImplements(ClassDescriptor cd){
        if (cd instanceof ClassDescriptor.Implements){
            ClassDescriptor.Implements cim = (ClassDescriptor.Implements)cd;
            if (cim.hasInterfaces()){
                lxl.List<Object> ili = cim.getInterfaces();
                int count = ili.size();
                if (0 != count){
                    String[] re = new String[count];
                    for (int cc = 0; cc < count; cc++)
                        re[cc] = ili.get(cc).toString();

                    return re;
                }
            }
        }
        return new String[0];
    }
    public final static Class FieldClass(PackageDescriptor pkg, FieldDescriptor field, lxl.List<ImportDescriptor> imports){
        String packageName = Classes.PackageName(pkg);
        String typeName = Classes.ToString(field.getType());
        return Classes.FieldClass(packageName,typeName,imports);
    }
    public final static Class FieldClass(PackageDescriptor pkg, String typeName, lxl.List<ImportDescriptor> imports){
        String packageName = Classes.PackageName(pkg);
        return Classes.FieldClass(packageName,typeName,imports);
    }
    public final static Class FieldClass(String pkg, String fieldType, lxl.List<ImportDescriptor> imports){
        String cleanTypeName = CleanTypeName(fieldType);
        Primitive primitive = Primitive.For(cleanTypeName);
        if (null != primitive)
            return primitive.type;
        else {
            gap.data.List.Type listType = gap.data.List.Type.For(cleanTypeName);
            if (null != listType)
                return listType.type;
            else {
                gap.data.Map.Type mapType = gap.data.Map.Type.For(cleanTypeName);
                if (null != mapType)
                    return mapType.type;
                else {
                    try {
                        return java.lang.Class.forName(cleanTypeName);
                    }
                    catch (java.lang.ClassNotFoundException exc){
                    }
                    for (ImportDescriptor imp : imports){
                        java.lang.Class clas = ClassFor(cleanTypeName,imp);
                        if (null != clas)
                            return clas;
                    }
                    try {
                        String classname = pkg+'.'+cleanTypeName;
                        return java.lang.Class.forName(classname);
                    }
                    catch (java.lang.ClassNotFoundException exc){
                    }
                    try {
                        String classname = "java.lang."+cleanTypeName;
                        return java.lang.Class.forName(classname);
                    }
                    catch (java.lang.ClassNotFoundException exc){
                    }
                    return null;
                }
            }
        }
    }
    public final static boolean IsFieldShort(ClassDescriptor container,
                                             FieldDescriptor field, ClassDescriptor fieldType)
    {
        boolean isShort = false;
        if (fieldType instanceof ClassDescriptor.Relation){
            ClassDescriptor.Relation fieldTypeR = (ClassDescriptor.Relation)fieldType;
            if (fieldTypeR.isRelationSecondary())
                isShort = true;
        }
        if (container.isFieldShort(field)){

            if (isShort)
                return true;
            else
                throw new ODStateException(field,"Field class '"+gap.Objects.StringFromObject(field.getType())+"' is used in a short relation from class '"+GetPackageClassName(container)+"', but is not declared 'child'.  This redundancy is required for type integrity.");
        }
        else if (isShort){

            throw new ODStateException(field,"Field class '"+gap.Objects.StringFromObject(field.getType())+"' is declared 'child' but not declared 'child' in class '"+GetPackageClassName(container)+"'.  This redundancy is required for type integrity.");
        }
        else
            return false;
    }
    /**
     * Explicit qualification or extant class member of enum -- for
     * symbolic enumerated type storage as string "pkg.class#field".
     */
    public final static boolean IsFieldEnumerated(FieldDescriptor field, ClassDescriptor fieldType, Class fieldClass){
        if (field instanceof FieldDescriptor.Enumerated){
            if ( ((FieldDescriptor.Enumerated)field).isEnumerated())
                return true;
        }

        if (null != fieldClass && Enum.class.isAssignableFrom(fieldClass))
            return true;
        else
            return false;
    }
    public final static String ListChildClassName(FieldDescriptor field){
        String typeName = Classes.ToString(field.getType());
        String[] parameters = FieldTypeParameters(typeName);
        if (null != parameters && 1 == parameters.length)
            return parameters[0];
        else
            return null;
    }
    /**
     * Parse map type components.  A map type field declaration
     * requires its key component declared from the child class in
     * 'FieldType:fieldName' format, as in
     * 'Map.Short&lt;String:name,TableClass&gt;' (for field type
     * 'String' name 'name' in child 'TableClass').
     */
    public final static class MapChild
        extends Object
    {
        public final static String ClassName(FieldDescriptor field){
            String typeName = Classes.ToString(field.getType());
            String[] parameters = FieldTypeParameters(typeName);
            if (null != parameters && 2 == parameters.length)
                return parameters[1];
            else
                return null;
        }
        /**
         * Normalize Type string.
         */
        public final static String Type(String type){
            int idx0 = type.indexOf(':');
            if (-1 != idx0){
                int idx1 = type.indexOf(',',idx0);
                if (-1 != idx1){
                    return (type.substring(0,idx0)+type.substring(idx1));
                }
            }
            return type;
        }
        /**
         * Normalize Type parameter string.
         */
        public final static String TypeKey(String type){
            int idx = type.indexOf(':');
            if (-1 != idx)
                return (type.substring(0,idx));
            else
                return type;
        }

        public final String fieldTypeDeclaration, fieldTypeName;
        public final gap.data.Map.Type mapType;
        public final gap.Primitive keyType;
        public final String childKeyFieldType, childKeyFieldName, childValueClassName;

        public MapChild(FieldDescriptor field)
            throws ODStateException
        {
            super();
            String fieldTypeDeclaration = Classes.ToString(field.getType());
            this.fieldTypeDeclaration = fieldTypeDeclaration;
            this.mapType = gap.data.Map.Type.For(fieldTypeDeclaration);
            String[] parameters = FieldTypeParameters(fieldTypeDeclaration);
            if (null != parameters && 2 == parameters.length){
                this.childValueClassName = parameters[1];
                String childKeyField = parameters[0];
                int idx = childKeyField.indexOf(':');
                if (-1 != idx){
                    this.childKeyFieldType = childKeyField.substring(0,idx);
                    try {
                        this.keyType = gap.Primitive.valueOf(this.childKeyFieldType);
                        this.childKeyFieldName = childKeyField.substring(idx+1);
                        this.fieldTypeName = this.mapType.dotName+'<'+this.childKeyFieldType+','+this.childValueClassName+'>';
                    }
                    catch (IllegalArgumentException notPrimitive){
                        throw new ODStateException(field,"Map type parameter key '"+this.childKeyFieldType+"' not primitive.",notPrimitive);
                    }
                }
                else
                    throw new ODStateException(field,"Map type requires key component 'type:fieldName' as in 'Map.Short<String:name,TableClass>'.");
            }
            else
                throw new ODStateException(field,"Map type parameters not found.");
        }
    }
    public final static boolean IsClassRelationPrimary(ClassDescriptor cd){
        if (cd instanceof ClassDescriptor.Relation){
            ClassDescriptor.Relation cdr = (ClassDescriptor.Relation)cd;
            return cdr.isRelationPrimary();
        }
        else
            return true;
    }
    public final static String[] FieldTypeParameters(String typeName){
        int start = typeName.indexOf('<');
        if (-1 != start){
            String parameters = typeName.substring((start+1),(typeName.length()-1)).trim();
            StringTokenizer strtok = new StringTokenizer(parameters,", ");
            int count = strtok.countTokens();
            String[] list = new String[count];
            for (int cc = 0; cc < count; cc++){
                String token = strtok.nextToken();
                if ('<' != token.charAt(0))
                    list[cc] = token;
                else
                    throw new IllegalStateException(typeName);
            }
            return list;
        }
        return new String[0];
    }
    public final static boolean IsFieldPersistent(FieldDescriptor field, Class fieldTypeClass){

        if (IsTypeClassBigTable(field,fieldTypeClass))

            return IsFieldPersistent(field);

        else if (IsTypeClassCollection(field,fieldTypeClass))

            return false;

        else if (IsFieldRelation(field)) /*(very template specific -- will change)
                                          */
            return false;

        else
            return IsFieldPersistent(field);
    }
    public final static boolean IsFieldPersistent(FieldDescriptor field){

        if (field instanceof FieldDescriptor.Persistence){
            FieldDescriptor.Persistence pfield = (FieldDescriptor.Persistence)field;
            if (pfield.hasPersistence()){
                if (FieldDescriptor.Persistence.Type.Transient.equals(pfield.getPersistence()))
                    return false;
                else
                    return true;
            }
            else
                return true;
        }
        else
            return true;
    }
    public final static boolean IsFieldUnique(FieldDescriptor field){
        if (field instanceof FieldDescriptor.Uniqueness){
            FieldDescriptor.Uniqueness ufield = (FieldDescriptor.Uniqueness)field;
            return (ufield.isUnique());
        }
        else
            return false;
    }
    public final static boolean IsFieldRelation(FieldDescriptor field){
        if (field instanceof FieldDescriptor.Relation){
            FieldDescriptor.Relation rfield = (FieldDescriptor.Relation)field;
            if (rfield.hasRelation()){
                FieldDescriptor.Relation.Type rtype = rfield.getRelation();
                if (FieldDescriptor.Relation.Type.None.equals(rtype))
                    return false;
                else
                    return true;
            }
            else
                return false;
        }
        else
            return false;
    }
    public final static boolean IsFieldRelationChild(FieldDescriptor field){
        if (field instanceof FieldDescriptor.Relation){
            FieldDescriptor.Relation rfield = (FieldDescriptor.Relation)field;
            if (rfield.hasRelation()){
                FieldDescriptor.Relation.Type rtype = rfield.getRelation();
                if (FieldDescriptor.Relation.Type.Child.equals(rtype))
                    return true;
                else
                    return false;
            }
            else
                return false;
        }
        else
            return false;
    }
    public final static boolean IsFieldRelationParent(FieldDescriptor field){
        if (field instanceof FieldDescriptor.Relation){
            FieldDescriptor.Relation rfield = (FieldDescriptor.Relation)field;
            if (rfield.hasRelation()){
                FieldDescriptor.Relation.Type rtype = rfield.getRelation();
                if (FieldDescriptor.Relation.Type.Parent.equals(rtype))
                    return true;
                else
                    return false;
            }
            else
                return false;
        }
        else
            return false;
    }
    public final static boolean IsFieldDefaultSortBy(FieldDescriptor field){
        if (field instanceof FieldDescriptor.DefaultSortBy){
            FieldDescriptor.DefaultSortBy sfield = (FieldDescriptor.DefaultSortBy)field;
            return sfield.isDefaultSortBy();
        }
        else
            return false;
    }
    public final static boolean IsTypeClassKey(java.lang.Class jclass){
        if (null != jclass)
            return (com.google.appengine.api.datastore.Key.class.equals(jclass));
        else
            return false;
    }
    public final static boolean IsTypeClassIndexed(java.lang.Class jclass){
        if (null != jclass)
            return DataTypeUtils.isSupportedType(jclass);
        else
            return false;
    }
    public final static boolean IsTypeClassList(java.lang.Class jclass){
        if (null != jclass)
            return ((!gap.data.Map.class.isAssignableFrom(jclass)) &&
                    gap.data.List.class.isAssignableFrom(jclass));
        else
            return false;
    }
    public final static boolean IsTypeClassBigTable(FieldDescriptor fd, java.lang.Class fieldType){
        if (null != fieldType)
            return (gap.data.TableClass.class.isAssignableFrom(fieldType));
        else {
            try {
                return (null != Classes.For(fd.getType()));
            }
            catch (java.io.IOException exc){
                throw new RuntimeException(exc);
            }
        }
    }
    /**
     * A Table Class member interface has no definition
     */
    public final static boolean IsTypeClassBigTableInterface(ClassDescriptor cd){
        /*
         * Is a pseudo descriptor (definition not found)
         */
        return (cd instanceof gap.util.ClassNameDescriptor);
    }
    public final static boolean IsTypeClassBigTable(ClassDescriptor cd, java.lang.Class jclass){
        if (null != cd)
            return true;
        else if (null != jclass)
            return (gap.data.TableClass.class.isAssignableFrom(jclass));
        else
            return false;
    }
    public final static boolean IsNotTypeClassBigTable(java.lang.Class jclass){
        if (null != jclass)
            return (!(gap.data.TableClass.class.isAssignableFrom(jclass)));
        else
            return true;
    }
    public final static boolean IsTypeClassMap(java.lang.Class jclass){
        if (null != jclass)
            return (gap.data.Map.class.isAssignableFrom(jclass));
        else
            return false;
    }
    public final static boolean IsTypeClassString(java.lang.Class jclass){
        if (null != jclass)
            return (java.lang.String.class.equals(jclass));
        else
            return false;
    }
    public final static boolean IsTypeClassDate(java.lang.Class jclass){
        if (null != jclass)
            return (java.util.Date.class.isAssignableFrom(jclass));
        else
            return false;
    }
    public final static boolean IsTypeClassCollection(FieldDescriptor field, java.lang.Class jclass){
        if (null != jclass)
            return (gap.data.Collection.class.isAssignableFrom(jclass));
  else if (null != field){
      String type = ToString(field.getType());
      return (gap.data.List.Type.Is(type) || gap.data.Map.Type.Is(type));
  }
        else
            return true;
    }
    public final static boolean IsNotTypeClassCollection(java.lang.Class jclass){
        if (null != jclass)
            return (!(gap.data.Collection.class.isAssignableFrom(jclass)));
        else
            return true;
    }
    public final static String CleanTypeName(String name){
        int idx = name.indexOf('<');
        if (-1 != idx)
            return name.substring(0,idx);
        else
            return name;
    }
    public final static String CleanCleanTypeName(String name){
        int idx = name.indexOf('.');
        if (-1 != idx)
            return name.substring(0,idx);
        else
            return name;
    }
    private final static Class ClassFor(String cleanTypeName, ImportDescriptor imp){
        if (imp.hasPackageSpec()){
            String packageSpec = imp.getPackageSpec();
            if (packageSpec.endsWith(".*")){
                packageSpec = packageSpec.substring(0,packageSpec.length()-1);
                String packageClassName = packageSpec+cleanTypeName;
                try {
                    return Class.forName(packageClassName);
                }
                catch (ClassNotFoundException exc){
                    return null;
                }
            }
            else
                throw new ODStateException(imp,"Import descriptor package spec missing dot-star suffix '"+packageSpec+"'.");
        }
        else if (imp.hasClassName()){
            String packageClassName = imp.getClassName();
            if (packageClassName.endsWith("."+cleanTypeName)){
                try {
                    return Class.forName(packageClassName);
                }
                catch (NoClassDefFoundError err){
                    return null;
                }
                catch (ClassNotFoundException exc){
                    return null;
                }
            }
            else
                return null;
        }
        else
            return null;
    }
    /**
     * @return String class name for type name explicit match to import
     */
    private final static String ClassNameIn(String cleanTypeName, ImportDescriptor imp){

        if (imp.hasClassName()){
            String packageClassName = imp.getClassName();
            if (packageClassName.endsWith("."+cleanTypeName)){

                return packageClassName;
            }
            else
                return null;
        }
        else
            return null;
    }
    public final static String ToString(Object object){
        if (object instanceof String)
            return (String)object;
        else if (object instanceof HasName)
            return ((HasName)object).getName();
        else
            return object.toString();
    }
    public final static String PackageName(Primitive pd){
        return pd.pkg;
    }
    public final static String PackageName(PackageDescriptor pkg)
        throws ODStateException
    {
        String packageName = pkg.getName();
        if (null == packageName || 0 == packageName.length())
            throw new ODStateException(pkg,"The object data model requires a package name.");

        return Decamel(packageName);
    }
    public final static String PackageName(Class uc)
        throws ODStateException
    {
        String className = uc.getName();
        int idx = className.lastIndexOf('.');
        if (-1 != idx)
            return className.substring(0,idx);
        else
            return null;
    }
    public final static String PackageName(ClassDescriptor cd)
        throws ODStateException
    {
        PackageDescriptor pd = PackageFor(cd);
        if (null != pd)
            return pd.getName();
        else
            throw new ODStateException(cd,"The object data model requires a package name.");
    }
    public final static String ClassName(Primitive pd){
        return pd.local;
    }
    public final static String ClassName(ClassDescriptor cd)
        throws ODStateException
    {
        String className = cd.getName();
        if (null == className || 0 == className.length())
            throw new ODStateException(cd,"The object data model requires a class name.");
        else
            return Camel(className);
    }
    public final static String ClassName(Class uc)
        throws ODStateException
    {
        String className = uc.getName();
        int idx = className.lastIndexOf('.');
        if (-1 != idx)
            return Camel(className.substring(idx+1));
        else
            return Camel(className);
    }
    public final static String FullClassName(ClassDescriptor cd, java.lang.Class jclass){
        if (null != jclass)
            return jclass.getName();
        else if (null != cd)
            return PackageName(cd) +'.'+ ClassName(cd);
        else
            throw new IllegalStateException();
    }
    public final static String ListImplClassName(String fieldType, String parentClassName, ClassDescriptor childType){

        return ListImplClassName(parentClassName,childType.getName());
    }
    public final static String ListPrimitiveClassName(Primitive childType){
        if (null != childType)
            return "ListPrimitive"+childType.name();
        else
            return null;
    }
    public final static String ListShortClassName(ClassDescriptor cd, FieldDescriptor fd){
        String parentClassName = ClassName(cd);
        String childClassName = ListChildClassName(fd);
        return ListShortClassName(parentClassName,childClassName);
    }
    public final static String ListShortClassName(String parentClassName, String childClassName){
        if (null != parentClassName && null != childClassName)
            return "ListShort"+parentClassName+childClassName;
        else
            return null;
    }
    public final static String ListLongClassName(ClassDescriptor cd, FieldDescriptor fd){
        String parentClassName = ClassName(cd);
        String childClassName = ListChildClassName(fd);
        return ListLongClassName(parentClassName,childClassName);
    }
    public final static String ListLongClassName(String parentClassName, String childClassName){
        if (null != parentClassName && null != childClassName)
            return "ListLong"+parentClassName+childClassName;
        else
            return null;
    }
    public final static String ListImplClassName(String parentClassName, String childClassName){
        if (null != parentClassName && null != childClassName)
            return "List"+parentClassName+childClassName;
        else
            return null;
    }
    public final static String MapClassName(String fieldType, String parentClassName, String typeComponentFrom, String typeComponentTo){
        gap.data.Map.Type mapType = gap.data.Map.Type.For(fieldType);
        if (null != mapType){
            switch(mapType){
            case MapPrimitive:
                return MapPrimitiveClassName(parentClassName,typeComponentFrom,typeComponentTo);
            case MapShort:
                return MapShortClassName(parentClassName,typeComponentFrom,typeComponentTo);
            case MapLong:
                return MapLongClassName(parentClassName,typeComponentFrom,typeComponentTo);
            default:
                throw new IllegalStateException("Unrecognized type '"+fieldType+"'.");
            }
        }
        else
            throw new IllegalStateException("Type '"+fieldType+"' requires qualifier {Map.Primitive,Map.Short,Map.Long}.");
    }
    public final static String MapPrimitiveClassName(String parentClassName, Classes.MapChild mapChild){
        if (null != parentClassName && null != mapChild)
            return MapPrimitiveClassName(parentClassName,mapChild.childKeyFieldType,mapChild.childValueClassName);
        else
            throw new IllegalArgumentException();
    }
    public final static String MapPrimitiveClassName(String parentClassName, String typeComponentFrom, String typeComponentTo){
        if (null != typeComponentFrom && null != typeComponentTo)
            return "MapPrimitive"+parentClassName+typeComponentFrom+typeComponentTo;
        else
            return null;
    }
    public final static String MapShortClassName(String parentClassName, Classes.MapChild mapChild){
        if (null != parentClassName && null != mapChild)
            return MapShortClassName(parentClassName,mapChild.childKeyFieldType,mapChild.childValueClassName);
        else
            throw new IllegalArgumentException();
    }
    public final static String MapShortClassName(String parentClassName, String typeComponentFrom, String typeComponentTo){
        if (null != parentClassName && null != typeComponentFrom && null != typeComponentTo)
            return "MapShort"+parentClassName+typeComponentFrom+typeComponentTo;
        else
            return null;
    }
    public final static String MapLongClassName(String parentClassName, Classes.MapChild mapChild){
        if (null != parentClassName && null != mapChild)
            return MapLongClassName(parentClassName,mapChild.childKeyFieldType,mapChild.childValueClassName);
        else
            throw new IllegalArgumentException();
    }
    public final static String MapLongClassName(String parentClassName, String typeComponentFrom, String typeComponentTo){
        if (null != parentClassName && null != typeComponentFrom && null != typeComponentTo)
            return "MapLong"+parentClassName+typeComponentFrom+typeComponentTo;
        else
            return null;
    }
    public final static FieldDescriptor KeyField(String packageName, ClassDescriptor cd, lxl.List<ImportDescriptor> imports){
        if (cd.hasFields()){
            for (FieldDescriptor field : cd.getFields()){
                String fieldType = ToString(field.getType());
                Class fieldTypeClass = FieldClass(packageName,fieldType,imports);
                if (IsTypeClassKey(fieldTypeClass)){
                    return field;
                }
            }
        }
        return null;
    }
    public final static FieldDescriptor FindFieldFor(ClassDescriptor parent, ClassDescriptor child){
        if (null != parent && null != child){
            if (parent.hasFields()){
                for (FieldDescriptor parentField : parent.getFields()){
                    String parentFieldType = ToString(parentField.getType());
                    gap.data.List.Type listType = gap.data.List.Type.For(parentFieldType);
                    if (null != listType){
                        String[] parentFieldTypeParameters = FieldTypeParameters(parentFieldType);
                        if (null != parentFieldTypeParameters && 1 == parentFieldTypeParameters.length){
                            String childFieldType = parentFieldTypeParameters[0];
                            if (childFieldType.equals(child.getName()))
                                return parentField;
                        }
                    }
                    else {
                        gap.data.Map.Type mapType = gap.data.Map.Type.For(parentFieldType);
                        if (null != mapType){
                            String[] parentFieldTypeParameters = FieldTypeParameters(parentFieldType);
                            if (null != parentFieldTypeParameters && 2 == parentFieldTypeParameters.length){
                                String childFieldType = parentFieldTypeParameters[1];
                                if (childFieldType.equals(child.getName()))
                                    return parentField;
                            }
                        }
                    }
                }
            }
            throw new ODStateException(child,"Child relation field not found in parent.");
        }
        else
            throw new IllegalArgumentException();
    }
    public final static boolean IsFieldShortIn(ClassDescriptor parent, ClassDescriptor child){
        FieldDescriptor parentField = FindFieldFor(parent,child);
        String parentFieldType = ToString(parentField.getType());
        gap.data.List.Type listType = gap.data.List.Type.For(parentFieldType);
        if (null != listType){
            switch (listType){
            case ListPrimitive:
                return false;
            case ListLong:
                return false;
            case ListShort:
                return true;
            default:
                throw new ODStateException(child,"Unrecognized list type.");
            }
        }
        else {
            gap.data.Map.Type mapType = gap.data.Map.Type.For(parentFieldType);
            if (null != mapType){
                switch (mapType){
                case MapPrimitive:
                    return false;
                case MapLong:
                    return false;
                case MapShort:
                    return true;
                default:
                    throw new ODStateException(child,"Unrecognized map type.");
                }
            }
            else
                throw new ODStateException(child,"Unrecognized field type.");
        }
    }
    public final static lxl.List<FieldDescriptor> FieldsOfTypeList(PackageDescriptor pkg, ClassDescriptor cd, lxl.List<ImportDescriptor> imports){
        lxl.List<FieldDescriptor> re = new lxl.ArrayList<FieldDescriptor>();
        if (cd.hasFields()){
            String packageName = Classes.PackageName(pkg);
            for (FieldDescriptor field : cd.getFields()){
                String typeName = Classes.ToString(field.getType());
                Class typeClass = Classes.FieldClass(packageName,typeName,imports);
                if (IsTypeClassList(typeClass)){
                    re.add(field);
                }
            }
        }
        return re;
    }
    public final static lxl.List<FieldDescriptor> FieldsOfTypeMap(PackageDescriptor pkg, ClassDescriptor cd, lxl.List<ImportDescriptor> imports){
        lxl.List<FieldDescriptor> re = new lxl.ArrayList<FieldDescriptor>();
        if (cd.hasFields()){
            String packageName = Classes.PackageName(pkg);
            for (FieldDescriptor field : cd.getFields()){
                String typeName = Classes.ToString(field.getType());
                Class typeClass = Classes.FieldClass(packageName,typeName,imports);
                if (IsTypeClassMap(typeClass)){
                    re.add(field);
                }
            }
        }
        return re;
    }
    public final static boolean IsTypeOf(String typeName, String interfaceName){
        if (gap.Primitive.Is(typeName))
            return false;
        else {
            try {
                ClassDescriptor type = Classes.For(typeName);
                if (null != type){
                    if (type instanceof ClassDescriptor.Implements){
                        ClassDescriptor.Implements typei = (ClassDescriptor.Implements)type;
                        if (typei.hasInterfaces()){
                            for (Object inf : typei.getInterfaces()){
                                String infName = ToString(inf);
                                if (interfaceName.equals(infName))
                                    return true;
                            }
                        }
                    }
                }
            }
            catch (Exception ignore){
                ignore.printStackTrace();//(only likely at dev time)
            }
            return false;
        }
    }
    public final static String WebXmlPathStar(ClassDescriptor cd){
        String path = ClassPath(cd);
        if (null != path && 0 != path.length()){
            StringBuilder string = new StringBuilder();
            if ('/' != path.charAt(0))
                string.append('/');
            string.append(path);
            string.append("/*");
            return string.toString();
        }
        else
            throw new IllegalStateException("Missing path for class '"+cd.getName()+"'");
    }
    private final static lxl.Map<String,Boolean> DisallowedFieldNames = new lxl.Map<String,Boolean>();
    static {
        DisallowedFieldNames.put("id",Boolean.FALSE);
        DisallowedFieldNames.put("key",Boolean.FALSE);
        DisallowedFieldNames.put("fromDatastore",Boolean.FALSE);
        DisallowedFieldNames.put("fromMemcache",Boolean.FALSE);
        DisallowedFieldNames.put("datastoreEntity",Boolean.FALSE);
        DisallowedFieldNames.put("inheritFromKey",Boolean.FALSE);
        DisallowedFieldNames.put("lock",Boolean.FALSE);
        DisallowedFieldNames.put("dirty",Boolean.FALSE);
        DisallowedFieldNames.put("clean",Boolean.FALSE);
    }
    /**
     * Disallowed field names include "id", "key", "fromDatastore",
     * "datastoreEntity", "dirty", "clean", and "lock".
     * @see gap.data.BigTable
     */
    public final static boolean IsFieldNameIllegal(String name){
        if (null != name && 0 < name.length())
            return (null != DisallowedFieldNames.get(name));
        else
            return true;
    }
}
TOP

Related Classes of gap.service.Classes

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.