All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.qlexpress4.aparser.ImportManager Maven / Gradle / Ivy

package com.alibaba.qlexpress4.aparser;

import com.alibaba.qlexpress4.ClassSupplier;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Author: DQinYuan
 */
public class ImportManager {

    private final ClassSupplier classSupplier;

    private final List importedPacks;

    private final Map> importedClses;

    public ImportManager(ClassSupplier classSupplier, List imports) {
        this.classSupplier = classSupplier;
        this.importedPacks = new ArrayList<>();
        this.importedClses = new HashMap<>();
        imports.forEach(this::addImport);
    }

    public ImportManager(ClassSupplier classSupplier, List importedPacks,
                         Map> importedClses) {
        this.classSupplier = classSupplier;
        this.importedPacks = importedPacks;
        this.importedClses = importedClses;
    }

    public boolean addImport(QLImport anImport) {
        switch (anImport.getScope()) {
            case PACK:
            case InnerCls:
                importedPacks.add(anImport);
                return true;
            case CLS:
                Class importCls = classSupplier.loadCls(anImport.getTarget());
                if (importCls == null) {
                    return false;
                }
                String[] split = anImport.getTarget().split("\\.");
                importedClses.put(split[split.length-1], importCls);
                return true;
            default:
                return false;
        }
    }

    public Class loadQualified(String qualifiedCls) {
        return classSupplier.loadCls(qualifiedCls);
    }

    public LoadPartQualifiedResult loadPartQualified(List fieldIds) {
        Class qualifiedCls = null;
        List qualifiedPath = null;
        String innerClsId = null;
        final byte initState = 0;
        final byte continueState = 1;
        final byte loadClsState = 2;
        final byte loadInnerClsState = 3;
        final byte preLoadInnerClsState = 4;
        byte state = initState;
        nextField:
        for (int i = 0; i < fieldIds.size(); i++) {
            String fieldId = fieldIds.get(i);
            switch (state) {
                case initState:
                    // load from imported class
                    Class aCls = importedClses.get(fieldId);
                    if (aCls != null) {
                        qualifiedCls = aCls;
                        state = preLoadInnerClsState;
                        continue;
                    }
                    // load from imported packs
                    if (!Character.isLowerCase(fieldId.charAt(0))) {
                        for (QLImport importedPack : importedPacks) {
                            switch (importedPack.getScope()) {
                                case PACK:
                                    Class packCls = classSupplier.loadCls(
                                            importedPack.getTarget() + "." + fieldId);
                                    if (packCls != null) {
                                        qualifiedCls = packCls;
                                        state = preLoadInnerClsState;
                                        continue nextField;
                                    }
                                    break;
                                case InnerCls:
                                    Class innerCls = classSupplier.loadCls(
                                            importedPack.getTarget() + "$" + fieldId
                                    );
                                    if (innerCls != null) {
                                        qualifiedCls = innerCls;
                                        state = preLoadInnerClsState;
                                        continue nextField;
                                    }
                                    break;
                            }
                        }
                        return new LoadPartQualifiedResult(null, 0);
                    }
                    state = continueState;
                    qualifiedPath = new ArrayList<>();
                    qualifiedPath.add(fieldId);
                    break;
                case preLoadInnerClsState:
                    if (!Character.isLowerCase(fieldId.charAt(0))) {
                        state = loadInnerClsState;
                        innerClsId = fieldId;
                    } else {
                        return new LoadPartQualifiedResult(qualifiedCls, i);
                    }
                    break;
                case continueState:
                    qualifiedPath.add(fieldId);
                    if (!Character.isLowerCase(fieldId.charAt(0))) {
                        state = loadClsState;
                    }
                    break;
                case loadClsState:
                    qualifiedCls = classSupplier.loadCls(String.join(".", qualifiedPath));
                    if (qualifiedCls == null){
                        return new LoadPartQualifiedResult(null, 0);
                    }
                    if (!Character.isLowerCase(fieldId.charAt(0))) {
                        qualifiedPath = null;
                        innerClsId = fieldId;
                        state = loadInnerClsState;
                    } else {
                        return new LoadPartQualifiedResult(qualifiedCls, i);
                    }
                    break;
                case loadInnerClsState:
                    Class innerCls = classSupplier.loadCls(qualifiedCls.getName() + "$" + innerClsId);
                    if (innerCls == null) {
                        return new LoadPartQualifiedResult(qualifiedCls, i - 1);
                    }
                    if (!Character.isLowerCase(fieldId.charAt(0))) {
                        qualifiedCls = innerCls;
                        innerClsId = fieldId;
                    } else {
                        return new LoadPartQualifiedResult(innerCls, i);
                    }
                    break;
            }
        }

        switch (state) {
            case continueState:
                return new LoadPartQualifiedResult(null, 0);
            case loadClsState:
                qualifiedCls = classSupplier.loadCls(String.join(".", qualifiedPath));
                return qualifiedCls == null? new LoadPartQualifiedResult(null, fieldIds.size()):
                        new LoadPartQualifiedResult(qualifiedCls, fieldIds.size());
            case preLoadInnerClsState:
                return new LoadPartQualifiedResult(qualifiedCls, fieldIds.size());
            case loadInnerClsState:
                Class innerCls = classSupplier.loadCls(qualifiedCls.getName() + "$" + innerClsId);
                return innerCls == null? new LoadPartQualifiedResult(qualifiedCls, fieldIds.size() - 1):
                        new LoadPartQualifiedResult(innerCls, fieldIds.size());
            default:
                return new LoadPartQualifiedResult(null, 0);
        }
    }

    public static class LoadPartQualifiedResult {
        private final Class cls;
        /**
         * first no class path field index
         */
        private final int restIndex;

        public LoadPartQualifiedResult(Class cls, int restIndex) {
            this.cls = cls;
            this.restIndex = restIndex;
        }

        public Class getCls() {
            return cls;
        }

        public int getRestIndex() {
            return restIndex;
        }
    }

    enum ImportScope {
        // import java.lang.*;
        PACK,
        // import a.b.Cls.*
        InnerCls,
        // import java.lang.String;
        CLS
    }

    public static QLImport importInnerCls(String clsPath) {
        return new QLImport(ImportScope.InnerCls, clsPath);
    }

    public static QLImport importPack(String packPath) {
        return new QLImport(ImportScope.PACK, packPath);
    }

    public static QLImport importCls(String clsPath) {
        return new QLImport(ImportScope.CLS, clsPath);
    }

    public static class QLImport {
        private final ImportScope scope;
        private final String target;

        public QLImport(ImportScope scope, String target) {
            this.scope = scope;
            this.target = target;
        }

        public ImportScope getScope() {
            return scope;
        }

        public String getTarget() {
            return target;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy