com.huawei.streaming.cql.DriverContext.java Source code

Java tutorial

Introduction

Here is the source code for com.huawei.streaming.cql.DriverContext.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.huawei.streaming.cql;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.TreeMap;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.huawei.streaming.api.Application;
import com.huawei.streaming.api.UserFunction;
import com.huawei.streaming.api.streams.Schema;
import com.huawei.streaming.cql.builder.BuilderUtils;
import com.huawei.streaming.cql.exception.ExecutorException;
import com.huawei.streaming.cql.executor.FunctionRegistry;
import com.huawei.streaming.cql.executor.mergeuserdefinds.JarFilter;
import com.huawei.streaming.cql.semanticanalyzer.parser.context.CreateOperatorContext;
import com.huawei.streaming.cql.semanticanalyzer.parser.context.ParseContext;
import com.huawei.streaming.exception.ErrorCode;

/**
 * driver??
 * ??
 *
 */
public class DriverContext {
    private static final String FILE_PREFIX = "file://";

    private static final Logger LOG = LoggerFactory.getLogger(DriverContext.class);

    /**
     * ??????????
     */
    private static ThreadLocal<BuilderUtils> builderNameSpace = new ThreadLocal<BuilderUtils>();

    /**
     * session?
     */
    private static ThreadLocal<FunctionRegistry> functions = new ThreadLocal<FunctionRegistry>();

    /*
     * ??CQL??
     * ????
     */
    private List<String> cqls = Lists.newArrayList();

    /*
     * CQL?AST
     * ?cqls????
     */
    private List<ParseContext> parseContexts = Lists.newArrayList();

    /**
     * ????schema?
     */
    private List<Schema> schemas = Lists.newArrayList();

    /**
     * ??
     * ??XML??xml?Streaming-site?
     * ?
     */
    private TreeMap<String, String> userConfs = Maps.newTreeMap();

    /**
     * 
     * key??
     * value?
     */
    private TreeMap<String, UserFunction> userDefinedFunctions = Maps.newTreeMap();

    /**
     * ???
     * key: ???
     * value: ??
     */
    private TreeMap<String, CreateOperatorContext> userOperators = Maps.newTreeMap();

    /**
     * 
     */
    private List<String> userFiles = Lists.newArrayList();

    /**
     * ??load?app
     */
    private Application app;

    /**
     * CQL
     */
    private CQLResult queryResult;

    /**
     * <>
     */
    public DriverContext() {
        builderNameSpace.set(new BuilderUtils());
        functions.set(new FunctionRegistry());
    }

    public static ThreadLocal<FunctionRegistry> getFunctions() {
        return functions;
    }

    public static ThreadLocal<BuilderUtils> getBuilderNameSpace() {
        return builderNameSpace;
    }

    /**
     * classpathjar
     *
     * @param pathsToRemove jar
     * @throws IOException jar
     */
    private static void removeFromClassPath(String[] pathsToRemove) throws IOException {
        Thread curThread = Thread.currentThread();
        URLClassLoader loader = (URLClassLoader) curThread.getContextClassLoader();
        Set<URL> newPath = new HashSet<URL>(Arrays.asList(loader.getURLs()));

        if (pathsToRemove != null) {
            for (String onestr : pathsToRemove) {
                if (StringUtils.indexOf(onestr, FILE_PREFIX) == 0) {
                    onestr = StringUtils.substring(onestr, CQLConst.I_7);
                }

                URL oneurl = (new File(onestr)).toURI().toURL();
                newPath.remove(oneurl);
            }
        }

        loader = new URLClassLoader(newPath.toArray(new URL[0]));
        curThread.setContextClassLoader(loader);
    }

    public List<String> getUserFiles() {
        return userFiles;
    }

    public TreeMap<String, UserFunction> getUserDefinedFunctions() {
        return userDefinedFunctions;
    }

    /**
     * schema
     *
     * @param schema schema?
     */
    public void addSchema(Schema schema) {
        schemas.add(schema);
    }

    /**
     * ??
     *
     * @param key ?
     * @param value ?
     */
    public void addConf(String key, String value) {
        if (value == null) {
            userConfs.remove(key);
        } else {
            userConfs.put(key, value);
        }
    }

    /**
     * 
     *
     * @param userFunction 
     */
    public void addUserDefoundFunctions(UserFunction userFunction) {
        userDefinedFunctions.put(userFunction.getName(), userFunction);
    }

    /**
     * 
     *
     * @param functionName ??
     * @param checkExists ?
     */
    public void removeUserDefinedFunction(String functionName, boolean checkExists) {
        if (checkExists) {
            if (userDefinedFunctions.containsKey(functionName)) {
                userDefinedFunctions.remove(functionName);
            }

        } else {
            userDefinedFunctions.remove(functionName);
        }
    }

    /**
     * 
     *
     * @param file 
     */
    public void addFile(String file) {
        this.userFiles.add(file);
    }

    /**
     * jar??
     *
     * @param jar jar
     * @throws ExecutorException jar
     */
    public void addJar(String jar) throws ExecutorException {
        if (jar == null) {
            LOG.info("No jar add to class path.");
            return;
        }

        registerJar(jar);
        this.userFiles.add(jar);
    }

    /**
     * ?
     *
     */
    public void cleanApp() {
        app = null;
    }

    /**
     * 
     *
     * @param cql 
     */
    public void addCQLs(String cql) {
        cqls.add(cql);

    }

    /**
     * ?
     *
     * @param parseContext ?
     */
    public void addParseContext(ParseContext parseContext) {
        parseContexts.add(parseContext);
    }

    /**
     * 
     *
     */
    public void clean() {
        unRegisterJars();
        this.app = null;
        this.parseContexts.clear();
        this.cqls.clear();
        this.queryResult = null;
        this.schemas.clear();
        this.userConfs.clear();
        this.userFiles.clear();
        this.userDefinedFunctions.clear();
        this.userOperators.clear();
        builderNameSpace.remove();
        builderNameSpace.set(new BuilderUtils());
        functions.remove();
        functions.set(new FunctionRegistry());
    }

    public List<String> getCqls() {
        return cqls;
    }

    public Application getApp() {
        return app;
    }

    public void setApp(Application app) {
        this.app = app;
    }

    public CQLResult getQueryResult() {
        return queryResult;
    }

    public void setQueryResult(CQLResult queryResult) {
        this.queryResult = queryResult;
    }

    public List<Schema> getSchemas() {
        return schemas;
    }

    public TreeMap<String, String> getUserConfs() {
        return userConfs;
    }

    public List<ParseContext> getParseContexts() {
        return parseContexts;
    }

    private void registerJar(String jar) throws ExecutorException {

        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        ClassLoader newLoader = addToClassPath(loader, StringUtils.split(jar, ","));
        Thread.currentThread().setContextClassLoader(newLoader);
        LOG.info("Added " + jar + " to class path");

    }

    private ClassLoader addToClassPath(ClassLoader classLoader, String[] newPaths) throws ExecutorException {
        URLClassLoader loader = (URLClassLoader) classLoader;
        List<URL> curPath = Arrays.asList(loader.getURLs());
        List<URL> newPath = Lists.newArrayList();

        for (URL onePath : curPath) {
            newPath.add(onePath);
        }
        curPath = newPath;
        if (newPaths != null) {
            for (String onestr : newPaths) {
                if (StringUtils.indexOf(onestr, FILE_PREFIX) == 0) {
                    onestr = StringUtils.substring(onestr, CQLConst.I_7);
                }

                URL oneurl = getFileURL(onestr);

                if (!curPath.contains(oneurl)) {
                    curPath.add(oneurl);
                }
            }
        }

        return new URLClassLoader(curPath.toArray(new URL[0]), loader);
    }

    private URL getFileURL(String onestr) throws ExecutorException {
        try {
            return (new File(onestr)).toURI().toURL();
        } catch (MalformedURLException e) {
            ExecutorException exception = new ExecutorException(ErrorCode.SEMANTICANALYZE_REGISTER_JAR,
                    new File(onestr).getName());
            LOG.error("Failed to parse file path.", exception);
            throw exception;
        }
    }

    private void unRegisterJars() {
        LOG.info("unRegister jars from class loader.");
        for (String jar : this.userFiles) {
            if (jar == null) {
                LOG.info("No file to delete from class path.");
                continue;
            }

            if (JarFilter.isJarFile(jar)) {
                unRegisterJar(jar);
            }
        }
    }

    private void unRegisterJar(String jar) {
        try {
            removeFromClassPath(StringUtils.split(jar, ","));
            LOG.info("Deleted " + jar + " from class path");
        } catch (IOException e) {
            LOG.error("Unable to unRegister jar {} for io error.", jar);
        }
    }

    /**
     * ?
     * @param createOp ?
     */
    public void addUserOperator(CreateOperatorContext createOp) {
        userOperators.put(createOp.getOperatorName(), createOp);
    }

    public TreeMap<String, CreateOperatorContext> getUserOperators() {
        return userOperators;
    }

    public void setUserOperators(TreeMap<String, CreateOperatorContext> userOperators) {
        this.userOperators = userOperators;
    }

}