Java tutorial
/** * 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; } }