/**
* 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.mapping;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.huawei.streaming.datasource.IDataSource;
import com.huawei.streaming.datasource.RDBDataSource;
import com.huawei.streaming.operator.IInputStreamOperator;
import com.huawei.streaming.operator.IOutputStreamOperator;
import com.huawei.streaming.operator.inputstream.HeadStreamSourceOp;
import com.huawei.streaming.operator.inputstream.KafkaSourceOp;
import com.huawei.streaming.operator.inputstream.TCPClientInputOperator;
import com.huawei.streaming.operator.outputstream.ConsolePrintOp;
import com.huawei.streaming.operator.outputstream.KafkaFunctionOp;
import com.huawei.streaming.operator.outputstream.TCPSenderFuncOp;
import com.huawei.streaming.serde.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* CQL内置的输入流和输出流简写映射
* <p/>
* 不区分大小写
*
*/
public enum SimpleLexer
{
INPUT()
{
private final Map<String, String> INPUTOPERATOR_MAPPING = Maps.newConcurrentMap();
/**
* {@inheritDoc}
*/
@Override
public synchronized String getSimpleName(String fullName)
{
return baseGetSimpleName(fullName, INPUTOPERATOR_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
public synchronized String getFullName(String simpleName)
{
return baseGetFullName(simpleName, INPUTOPERATOR_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean register(String simpleName, Class<?> clazz)
{
return baseRegister(simpleName, clazz, INPUTOPERATOR_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean unRegister(String simpleName)
{
return baseUnRegister(simpleName, INPUTOPERATOR_MAPPING);
}
},
OUTPUT()
{
private final Map<String, String> OUTPUTOPERTOR_MAPPING = Maps.newConcurrentMap();
/**
* {@inheritDoc}
*/
@Override
public synchronized String getSimpleName(String fullName)
{
return baseGetSimpleName(fullName, OUTPUTOPERTOR_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
public synchronized String getFullName(String simpleName)
{
return baseGetFullName(simpleName, OUTPUTOPERTOR_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean register(String simpleName, Class<?> clazz)
{
return baseRegister(simpleName, clazz, OUTPUTOPERTOR_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean unRegister(String simpleName)
{
return baseUnRegister(simpleName, OUTPUTOPERTOR_MAPPING);
}
},
SERDE()
{
private final Map<String, String> SERDE_MAPPING = Maps.newConcurrentMap();
/**
* {@inheritDoc}
*/
@Override
public synchronized String getSimpleName(String fullName)
{
return baseGetSimpleName(fullName, SERDE_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
public synchronized String getFullName(String simpleName)
{
return baseGetFullName(simpleName, SERDE_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean register(String simpleName, Class<?> clazz)
{
return baseRegister(simpleName, clazz, SERDE_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean unRegister(String simpleName)
{
return baseUnRegister(simpleName, SERDE_MAPPING);
}
},
DATASOURCE()
{
private final Map<String, String> DATASOURCE_MAPPING = Maps.newConcurrentMap();
/**
* {@inheritDoc}
*/
@Override
public synchronized String getSimpleName(String fullName)
{
return baseGetSimpleName(fullName, DATASOURCE_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
public synchronized String getFullName(String simpleName)
{
return baseGetFullName(simpleName, DATASOURCE_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean register(String simpleName, Class<?> clazz)
{
return baseRegister(simpleName, clazz, DATASOURCE_MAPPING);
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized boolean unRegister(String simpleName)
{
return baseUnRegister(simpleName, DATASOURCE_MAPPING);
}
};
private static final Logger LOG = LoggerFactory.getLogger(SimpleLexer.class);
/**
* 通过全称获取简称,如果不存在,返回null
*/
public abstract String getSimpleName(String fullName);
/**
* 获取全称,如果不存在,返回null
*/
public abstract String getFullName(String simpleName);
/**
* 注册简称,
* 注意,注册可能会导致系统注册变量丢失,即使后面移除了注册,也不会恢复。
*/
protected abstract boolean register(String simpleName, Class<?> clazz);
/**
* 移除注册,如果返回false,移除失败,说明简称不存在
*/
protected abstract boolean unRegister(String simpleName);
static
{
//序列化反序列化类
registerSerDe("SimpleSerDe", SimpleSerDe.class);
registerSerDe("KeyValueSerDe", KeyValueSerDe.class);
registerSerDe("CsvSerDe", CSVSerDe.class);
registerSerDe("BinarySerDe", BinarySerDe.class);
registerInputOperator("KafkaInput", KafkaSourceOp.class);
registerInputOperator("TCPClientInput", TCPClientInputOperator.class);
registerInputOperator("RandomGen", HeadStreamSourceOp.class);
registerOutputOperator("KafkaOutput", KafkaFunctionOp.class);
registerOutputOperator("TCPClientOutput", TCPSenderFuncOp.class);
registerOutputOperator("ConsoleOutput", ConsolePrintOp.class);
registerDataSource("RDBDataSource", RDBDataSource.class);
}
/**
* 注册序列化类/反序列化类的简称
* 由于没有办法区分哪些是系统注册的,哪些是用户注册的,所以默认后注册的覆盖先注册的。
* 由泛型来对注册类进行限制,方式注册错误类,这样就可以在编译期发现问题。
*/
public static void registerSerDe(String name, Class<? extends StreamSerDe> clazz)
{
SERDE.register(name, clazz);
}
/**
* 注册各类算子简称,这里的算子,一定是包含了可执行接口的算子
* 由于没有办法区分哪些是系统注册的,哪些是用户注册的,所以默认后注册的覆盖先注册的。
* 由泛型来对注册类进行限制,方式注册错误类,这样就可以在编译期发现问题。
*/
public static void registerInputOperator(String name, Class<? extends IInputStreamOperator> clazz)
{
INPUT.register(name, clazz);
}
/**
* 注册各类算子简称,这里的算子,一定是包含了可执行接口的算子
* 由于没有办法区分哪些是系统注册的,哪些是用户注册的,所以默认后注册的覆盖先注册的。
* 由泛型来对注册类进行限制,方式注册错误类,这样就可以在编译期发现问题。
*/
public static void registerOutputOperator(String name, Class<? extends IOutputStreamOperator> clazz)
{
OUTPUT.register(name, clazz);
}
/**
* 注册数据源简称,这里的数据源,一定是包含了可执行接口的数据源接口实现
* 由于没有办法区分哪些是系统注册的,哪些是用户注册的,所以默认后注册的覆盖先注册的。
* 由泛型来对注册类进行限制,方式注册错误类,这样就可以在编译期发现问题。
*/
public static void registerDataSource(String name, Class<? extends IDataSource> clazz)
{
DATASOURCE.register(name, clazz);
}
/**
* 移除语法简称
*
*/
public static boolean unRegisterSerDe(String name)
{
return SERDE.unRegister(name);
}
/**
* 移除语法简称
*
*/
public static boolean unRegisterInput(String name)
{
return INPUT.unRegister(name);
}
/**
* 移除语法简称
*
*/
public static boolean unRegisterOutput(String name)
{
return OUTPUT.unRegister(name);
}
/**
* 移除语法简称
*
*/
public static boolean unRegisterDataSource(String name)
{
return DATASOURCE.unRegister(name);
}
//加入同步防止多线程同时添加或者删除导致的错误,虽然说map本身是同步的,但是方法并不同步
private synchronized static boolean baseUnRegister(String name, Map<String, String> mapping)
{
if (Strings.isNullOrEmpty(name))
{
LOG.warn("Failed to unRegister simple lexer mapping, name is null.");
return false;
}
//由于可能移除系统注册的简称,所以这里级别是Warn
LOG.warn("UnRegister '{}' from simple lexers.", name);
if (mapping.containsKey(name))
{
mapping.remove(name);
}
return true;
}
private synchronized static boolean baseRegister(String simpleName, Class<?> clazz, Map<String, String> mapping)
{
if (Strings.isNullOrEmpty(simpleName) || clazz == null)
{
LOG.warn("Failed to register simple lexer mapping, name or class is null.");
return false;
}
LOG.info("register simple lexer {}, class {}.", simpleName, clazz);
if (mapping.containsKey(simpleName))
{
LOG.warn("Exists simple lexxer {} will be repalced.", simpleName);
}
mapping.put(simpleName, clazz.getName());
return true;
}
private synchronized static String baseGetSimpleName(String fullName, Map<String, String> mapping)
{
if (fullName == null)
{
return null;
}
for (Map.Entry<String, String> et : mapping.entrySet())
{
if (fullName.equals(et.getValue()))
{
return et.getKey();
}
}
return null;
}
private synchronized static String baseGetFullName(String simpleName, Map<String, String> mapping)
{
if (Strings.isNullOrEmpty(simpleName))
{
return null;
}
for (Map.Entry<String, String> et : mapping.entrySet())
{
if (simpleName.equalsIgnoreCase(et.getKey()))
{
return et.getValue();
}
}
return null;
}
}