Browse Source

数据库/数据集插件示例

paid
richie 6 years ago
commit
b787d0897e
  1. 5
      .gitignore
  2. 130
      build.xml
  3. BIN
      lib/jedis-2.9.0.jar
  4. 0
      lib/report/.gitkepp
  5. 29
      plugin.xml
  6. 28
      pom.xml
  7. 42
      readme.md
  8. BIN
      screenshots/1.png
  9. BIN
      screenshots/2.png
  10. BIN
      screenshots/3.png
  11. 35
      src/main/java/com/fr/plugin/db/redis/RedisConnectionImpl.java
  12. 14
      src/main/java/com/fr/plugin/db/redis/RedisLocaleFinder.java
  13. 48
      src/main/java/com/fr/plugin/db/redis/RedisTableDataDefine.java
  14. 98
      src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManager.java
  15. 12
      src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManagerProvider.java
  16. 34
      src/main/java/com/fr/plugin/db/redis/core/DataWrapper.java
  17. 10
      src/main/java/com/fr/plugin/db/redis/core/RedisConstants.java
  18. 161
      src/main/java/com/fr/plugin/db/redis/core/RedisDatabaseConnection.java
  19. 26
      src/main/java/com/fr/plugin/db/redis/core/RedisMechanism.java
  20. 167
      src/main/java/com/fr/plugin/db/redis/core/RedisTableData.java
  21. 89
      src/main/java/com/fr/plugin/db/redis/core/RedisTableDataModel.java
  22. 48
      src/main/java/com/fr/plugin/db/redis/core/order/OrderValue.java
  23. 69
      src/main/java/com/fr/plugin/db/redis/core/order/impl/FormulaOrderValue.java
  24. 40
      src/main/java/com/fr/plugin/db/redis/core/order/impl/NumberOrderValue.java
  25. 28
      src/main/java/com/fr/plugin/db/redis/core/visit/AbstractVisitor.java
  26. 25
      src/main/java/com/fr/plugin/db/redis/core/visit/Visitor.java
  27. 50
      src/main/java/com/fr/plugin/db/redis/core/visit/VisitorFactory.java
  28. 32
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/GetVisitor.java
  29. 32
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashGetVisitor.java
  30. 32
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashKeysVisitor.java
  31. 35
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashMGetVisitor.java
  32. 39
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashVisitor.java
  33. 32
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/KeysVisitor.java
  34. 39
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/ListVisitor.java
  35. 34
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/MGetVisitor.java
  36. 38
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/SetVisitor.java
  37. 91
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/SingleArrayVisitor.java
  38. 46
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/ZRangeVisitor.java
  39. 80
      src/main/java/com/fr/plugin/db/redis/ui/RedisConnectionPane.java
  40. 143
      src/main/java/com/fr/plugin/db/redis/ui/RedisDBConnectionChosePane.java
  41. 94
      src/main/java/com/fr/plugin/db/redis/ui/RedisQueryPane.java
  42. 209
      src/main/java/com/fr/plugin/db/redis/ui/RedisTableDataPane.java
  43. 6
      src/main/java/com/fr/plugin/db/redis/ui/event/DataLoadedListener.java
  44. 142
      src/main/java/com/fr/plugin/db/redis/ui/value/FormulaEditor.java
  45. 20
      src/main/java/com/fr/plugin/db/redis/ui/value/IndexValuePaneFactory.java
  46. 114
      src/main/java/com/fr/plugin/db/redis/ui/value/IntegerEditor.java
  47. BIN
      src/main/resources/com/fr/plugin/db/redis/images/redis.png
  48. 10
      src/main/resources/com/fr/plugin/db/redis/locale/redis.properties
  49. 10
      src/main/resources/com/fr/plugin/db/redis/locale/redis_en_US.properties
  50. 10
      src/main/resources/com/fr/plugin/db/redis/locale/redis_zh_CN.properties

5
.gitignore vendored

@ -0,0 +1,5 @@
*.iml
.idea/
lib/report/*.jar
target/
.DS_Store

130
build.xml

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="jar" name="plugin">
<!-- JDK路径,根据自己机器上实际位置修改-->
<property name="jdk.home" value="/Library/Java/JavaVirtualMachines/JDK1.8/Contents/Home"/>
<property name="libs" value="${basedir}/lib"/>
<property name="publicLibs" value=""/>
<property name="reportLibs" value="${basedir}/../webroot/WEB-INF/lib"/>
<property name="destLoc" value="."/>
<property name="classes" value="classes"/>
<xmlproperty file="${basedir}/plugin.xml"/>
<property name="current-version" value="${plugin.version}"/>
<!-- 插件版本-->
<property name="plugin-version" value="${current-version}"/>
<!-- 插件名字-->
<property name="plugin-name" value="redis-db"/>
<property name="plugin-jar" value="fr-plugin-${plugin-name}-${plugin-version}.jar"/>
<target name="prepare">
<delete dir="${classes}"/>
<delete dir="fr-plugin-${plugin-name}-${plugin-version}"/>
<xmlproperty file="${basedir}/plugin.xml"/>
<delete dir="${destLoc}/${plugin.name}"/>
</target>
<bucket id="compile.classpath">
<fileset dir="${libs}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${publicLibs}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${reportLibs}">
<include name="**/*.jar"/>
</fileset>
</bucket>
<patternset id="resources4Jar">
<exclude name="**/.settings/**"/>
<exclude name=".classpath"/>
<exclude name=".project"/>
<exclude name="**/*.java"/>
<exclude name="**/*.db"/>
<exclude name="**/*.g"/>
<exclude name="**/package.html"/>
</patternset>
<target name="copy_resources">
<echo message="从${resources_from}拷贝图片,JS,CSS等资源文件"/>
<delete dir="tmp"/>
<copy todir="tmp">
<fileset dir="${resources_from}/src/main/resources">
<patternset refid="resources4Jar"/>
</fileset>
</copy>
<copy todir="${classes}">
<fileset dir="tmp"/>
</copy>
<delete dir="tmp"/>
</target>
<target name="compile_javas">
<echo message="编译${compile_files}下的Java文件"/>
<javac destdir="${classes}" debug="false" optimize="on" source="${source_jdk_version}"
target="${target_jdk_version}"
fork="true" memoryMaximumSize="512m" listfiles="false" srcdir="${basedir}"
executable="${compile_jdk_version}/bin/javac">
<src bucket="${basedir}/src/main/java"/>
<exclude name="**/.svn/**"/>
<compilerarg line="-encoding UTF8 "/>
<classpath refid="compile.classpath"/>
</javac>
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask">
<classpath refid="compile.classpath"/>
</taskdef>
<pretreatment baseDir="${basedir}"/>
</target>
<target name="jar_classes">
<echo message="打Jar包:${jar_name}"/>
<delete file="${basedir}/${jar_name}"/>
<jar jarfile="${basedir}/${jar_name}">
<fileset dir="${classes}">
</fileset>
</jar>
</target>
<target name="super_jar" depends="prepare">
<antcall target="copy_resources">
<param name="resources_from" value="${basedir}"/>
</antcall>
<antcall target="compile_javas">
<param name="source_jdk_version" value="1.6"/>
<param name="target_jdk_version" value="1.6"/>
<param name="compile_jdk_version" value="${jdk.home}"/>
<param name="compile_files" value="${basedir}/src"/>
</antcall>
<echo message="compile plugin success!"/>
<antcall target="jar_classes">
<param name="jar_name" value="${plugin-jar}"/>
</antcall>
<delete dir="${classes}"/>
</target>
<target name="jar" depends="super_jar">
<antcall target="zip"/>
</target>
<target name="zip">
<property name="plugin-folder" value="fr-plugin-${plugin-name}-${plugin-version}"/>
<echo message="----------zip files----------"/>
<mkdir dir="${plugin-folder}"/>
<copy todir="${plugin-folder}">
<fileset dir=".">
<include name="${plugin-jar}"/>
<include name="plugin.xml"/>
</fileset>
<fileset dir="${libs}">
<include name="*.jar"/>
<include name="*.dll"/>
</fileset>
</copy>
<zip destfile="${basedir}/${plugin-folder}.zip" basedir=".">
<include name="${plugin-folder}/*.jar"/>
<include name="${plugin-folder}/*.dll"/>
<include name="${plugin-folder}/plugin.xml"/>
</zip>
<move file="${plugin-folder}.zip" todir="${destLoc}/install"/>
</target>
</project>

BIN
lib/jedis-2.9.0.jar

Binary file not shown.

0
lib/report/.gitkepp

29
plugin.xml

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fr.solution.plugin.db.redis.v10</id>
<name><![CDATA[Redis数据集]]></name>
<active>yes</active>
<version>3.0</version>
<env-version>10.0</env-version>
<jartime>2018-08-20</jartime>
<vendor>richie</vendor>
<description><![CDATA[可以连接Redis数据库,支持哈希表、列表、集合以及有序集合]]></description>
<change-notes><![CDATA[
[2018-09-12]适配10.0版本。<br/>
[2018-05-12]增加了keys、hget、hmget、hkeys查询。<br/>
[2018-05-11]增加连接错误判定。<br/>
[2018-03-30]增加数据库编号选择。<br/>
[2017-04-18]连接Redis数据库。<br/>
]]></change-notes>
<extra-core>
<LocaleFinder class="com.fr.plugin.db.redis.RedisLocaleFinder"/>
</extra-core>
<extra-report>
</extra-report>
<extra-designer>
<ConnectionProvider class="com.fr.plugin.db.redis.RedisConnectionImpl"/>
<TableDataDefineProvider class="com.fr.plugin.db.redis.RedisTableDataDefine"/>
<ServerTableDataDefineProvider class="com.fr.plugin.db.redis.RedisTableDataDefine"/>
</extra-designer>
</plugin>

28
pom.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fr.plugin</groupId>
<artifactId>starter</artifactId>
<version>10.0</version>
</parent>
<packaging>jar</packaging>
<artifactId>demo-tabledata-redis</artifactId>
<build>
<!---如果要更改调试插件,改这里的配置就可以了-->
<outputDirectory>${project.basedir}/../webroot/WEB-INF/plugins/plugin-com.fr.solution.plugin.db.redis.v10-1.0/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

42
readme.md

@ -0,0 +1,42 @@
# 帆软报表连接redis缓存数据库插件
## 插件编译
进入插件源码目录,执行命名
`ant -f build.xml jar`
即可
## 插件安装
使用帆软设计器自带的插件管理器即可安装。
## 插件使用
### 新建数据连接
安装完插件后,在新建数据连接的地方可以看到Redis类型的数据连接,点击新建后可以看到如下的界面:
![1](screenshots/1.png)
按实际的配置填写上即可。
### 新建数据集
在模板数据集添加的地方会出现Redis数据集:
![1](screenshots/2.png)
点击新建后会出现如下的界面,输入查询条件即可:
![1](screenshots/3.png)
### 支持的查询语句
mget key [key ...]
hgetall key
lrange key 0 -1
smembers key
zrange key 0 -1
### 更多查询语句的支持
只需要实现com.fr.plugin.db.redis.core.visit.Visitor接口,并在VisitorFactory中注册即可。

BIN
screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

35
src/main/java/com/fr/plugin/db/redis/RedisConnectionImpl.java

@ -0,0 +1,35 @@
package com.fr.plugin.db.redis;
import com.fr.data.impl.Connection;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.fun.impl.AbstractConnectionProvider;
import com.fr.plugin.db.redis.core.RedisDatabaseConnection;
import com.fr.plugin.db.redis.ui.RedisConnectionPane;
public class RedisConnectionImpl extends AbstractConnectionProvider {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public String nameForConnection() {
return "Redis";
}
@Override
public String iconPathForConnection() {
return "/com/fr/plugin/db/redis/images/redis.png";
}
@Override
public Class<? extends Connection> classForConnection() {
return RedisDatabaseConnection.class;
}
@Override
public Class<? extends BasicBeanPane<? extends Connection>> appearanceForConnection() {
return RedisConnectionPane.class;
}
}

14
src/main/java/com/fr/plugin/db/redis/RedisLocaleFinder.java

@ -0,0 +1,14 @@
package com.fr.plugin.db.redis;
import com.fr.plugin.db.redis.core.RedisConstants;
import com.fr.stable.fun.Authorize;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
@Authorize(callSignKey = RedisConstants.PLUGIN_ID)
public class RedisLocaleFinder extends AbstractLocaleFinder {
@Override
public String find() {
return "com/fr/plugin/db/redis/locale/redis";
}
}

48
src/main/java/com/fr/plugin/db/redis/RedisTableDataDefine.java

@ -0,0 +1,48 @@
package com.fr.plugin.db.redis;
import com.fr.base.TableData;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.fun.ServerTableDataDefineProvider;
import com.fr.design.fun.impl.AbstractTableDataDefineProvider;
import com.fr.general.Inter;
import com.fr.plugin.db.redis.core.RedisTableData;
import com.fr.plugin.db.redis.ui.RedisTableDataPane;
public class RedisTableDataDefine extends AbstractTableDataDefineProvider implements ServerTableDataDefineProvider {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public Class<? extends TableData> classForTableData() {
return RedisTableData.class;
}
@Override
public Class<? extends TableData> classForInitTableData() {
return RedisTableData.class;
}
@Override
public Class<? extends AbstractTableDataPane> appearanceForTableData() {
return RedisTableDataPane.class;
}
@Override
public String nameForTableData() {
return Inter.getLocText("Plugin-Redis_Table_Data");
}
@Override
public String prefixForTableData() {
return "redis";
}
@Override
public String iconPathForTableData() {
return "/com/fr/plugin/db/redis/images/redis.png";
}
}

98
src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManager.java

@ -0,0 +1,98 @@
package com.fr.plugin.db.redis.conf;
import com.fr.file.XMLFileManager;
import com.fr.general.GeneralContext;
import com.fr.stable.EnvChangedListener;
import com.fr.stable.StringUtils;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLTools;
import com.fr.stable.xml.XMLableReader;
import java.io.InputStream;
/**
* Created by richie on 2017/6/5.
*/
public class ShellConfigManager extends XMLFileManager implements ShellConfigManagerProvider {
private static final String XML_TAG = "ShellConfigManager";
private static ShellConfigManagerProvider shellManager = null;
public synchronized static ShellConfigManager getInstance() {
return (ShellConfigManager) getProviderInstance();
}
public synchronized static ShellConfigManagerProvider getProviderInstance() {
if (shellManager == null) {
if (isClusterMember()) {
return shellManager;
}
shellManager.readXMLFile();
}
return shellManager;
}
private synchronized static boolean isClusterMember() {
return false;
}
static {
GeneralContext.addEnvChangedListener(new EnvChangedListener() {
public void envChanged() {
ShellConfigManager.envChanged();
}
});
}
private synchronized static void envChanged() {
shellManager = null;
}
private String shellText;
@Override
public String getShellText() {
return shellText;
}
public void setShellText(String shellText) {
this.shellText = shellText;
}
@Override
public void readXML(XMLableReader reader) {
if (reader.isAttr()) {
shellText = reader.getAttrAsString("shell", StringUtils.EMPTY);
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
writer.startTAG(XML_TAG);
writer.attr("shell", shellText);
writer.end();
}
@Override
public String fileName() {
return "redis.xml";
}
@Override
public void readFromInputStream(InputStream input) throws Exception {
// 服务器端新建一个对象
ShellConfigManager manager = new ShellConfigManager();
// 从客户端传过来的inputstream中读取对象属性
XMLTools.readInputStreamXML(manager, input);
// 赋值给当前服务器端对象
shellManager = manager;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

12
src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManagerProvider.java

@ -0,0 +1,12 @@
package com.fr.plugin.db.redis.conf;
import com.fr.stable.FCloneable;
import com.fr.stable.file.RemoteXMLFileManagerProvider;
/**
* Created by richie on 2017/6/5.
*/
public interface ShellConfigManagerProvider extends RemoteXMLFileManagerProvider, java.io.Serializable, FCloneable {
String getShellText();
}

34
src/main/java/com/fr/plugin/db/redis/core/DataWrapper.java

@ -0,0 +1,34 @@
package com.fr.plugin.db.redis.core;
import java.util.List;
/**
* Created by richie on 2017/6/5.
*/
public class DataWrapper<T> {
public static <T> DataWrapper<T> create(List<List<T>> data, String[] columnNames) {
return new DataWrapper<T>(data, columnNames);
}
public static DataWrapper EMPTY = new DataWrapper(null, RedisConstants.DEFAULT_COLUMN_NAMES);
private List<List<T>> data;
private String[] columnNames;
private DataWrapper(List<List<T>> data, String[] columnNames) {
this.data = data;
this.columnNames = columnNames;
}
public String[] getColumnNames() {
if (columnNames == null) {
return RedisConstants.DEFAULT_COLUMN_NAMES;
}
return columnNames;
}
public List<List<T>> getData() {
return data;
}
}

10
src/main/java/com/fr/plugin/db/redis/core/RedisConstants.java

@ -0,0 +1,10 @@
package com.fr.plugin.db.redis.core;
public class RedisConstants {
public static final String PLUGIN_ID = "com.fr.solution.plugin.db.redis.v10";
public static final int DEFAULT_DB_INDEX = 0;
public static final String[] DEFAULT_COLUMN_NAMES = new String[]{"text", "value"};
}

161
src/main/java/com/fr/plugin/db/redis/core/RedisDatabaseConnection.java

@ -0,0 +1,161 @@
package com.fr.plugin.db.redis.core;
import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.general.Inter;
import com.fr.stable.CodeUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;
import java.util.List;
public class RedisDatabaseConnection extends AbstractDatabaseConnection {
private static final int DEFAULT_REDIS_PORT = 6379;
private String host;
private int port = DEFAULT_REDIS_PORT;
private String password;
public RedisDatabaseConnection() {
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public void testConnection() throws Exception {
Jedis client = createRedisClient();
try {
String text = client.ping();
if (!"pong".equalsIgnoreCase(text)) {
throw new Exception(text);
}
} finally {
client.close();
}
}
public Jedis createRedisClient() {
Jedis client = new Jedis(host, port);
if (StringUtils.isNotEmpty(password)) {
client.auth(password);
}
return client;
}
@Override
public java.sql.Connection createConnection() throws Exception {
return null;
}
@Override
public String connectMessage(boolean status) {
if (status) {
return Inter.getLocText("Datasource-Connection_successfully") + "!";
} else {
return Inter.getLocText("Datasource-Connection_failed") + "!";
}
}
@Override
public void addConnection(List<String> list, String connectionName, Class<? extends Connection>[] acceptTypes) {
for (Class<? extends com.fr.data.impl.Connection> accept : acceptTypes) {
if (StableUtils.classInstanceOf(getClass(), accept)) {
list.add(connectionName);
break;
}
}
}
@Override
public String getDriver() {
return null;
}
@Override
public String getOriginalCharsetName() {
return null;
}
@Override
public void setOriginalCharsetName(String s) {
}
@Override
public String getNewCharsetName() {
return null;
}
@Override
public void setNewCharsetName(String s) {
}
@Override
public void readXML(XMLableReader reader) {
super.readXML(reader);
if (reader.isChildNode()) {
String tagName = reader.getTagName();
if ("Attr".equals(tagName)) {
host = reader.getAttrAsString("host", StringUtils.EMPTY);
port = reader.getAttrAsInt("port", DEFAULT_REDIS_PORT);
String pwd = reader.getAttrAsString("password", StringUtils.EMPTY);
if (StringUtils.isNotEmpty(pwd)) {
password = CodeUtils.passwordDecode(pwd);
}
}
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
super.writeXML(writer);
writer.startTAG("Attr");
writer.attr("host", host);
writer.attr("port", port);
if (StringUtils.isNotEmpty(password)) {
writer.attr("password", CodeUtils.passwordEncode(password));
}
writer.end();
}
@Override
public Object clone() throws CloneNotSupportedException {
com.fr.plugin.db.redis.core.RedisDatabaseConnection cloned = (com.fr.plugin.db.redis.core.RedisDatabaseConnection) super.clone();
cloned.host = host;
cloned.port = port;
cloned.password = password;
return cloned;
}
}

26
src/main/java/com/fr/plugin/db/redis/core/RedisMechanism.java

@ -0,0 +1,26 @@
package com.fr.plugin.db.redis.core;
public enum RedisMechanism {
NONE(0), SHA1(1),CR(2);
private int type;
RedisMechanism(int type) {
this.type = type;
}
public int toInt() {
return type;
}
public static RedisMechanism parse(int type) {
for (RedisMechanism m : RedisMechanism.values()) {
if (m.type == type) {
return m;
}
}
return RedisMechanism.NONE;
}
}

167
src/main/java/com/fr/plugin/db/redis/core/RedisTableData.java

@ -0,0 +1,167 @@
package com.fr.plugin.db.redis.core;
import com.fr.base.Parameter;
import com.fr.base.TableData;
import com.fr.base.TemplateUtils;
import com.fr.data.AbstractParameterTableData;
import com.fr.data.core.DataCoreXmlUtils;
import com.fr.data.impl.Connection;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.file.DatasourceManager;
import com.fr.general.Inter;
import com.fr.general.data.DataModel;
import com.fr.general.xml.GeneralXMLTools;
import com.fr.plugin.ExtraClassManager;
import com.fr.plugin.db.redis.core.order.OrderValue;
import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.fun.FunctionHelper;
import com.fr.stable.fun.FunctionProcessor;
import com.fr.stable.fun.impl.AbstractFunctionProcessor;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import java.util.HashMap;
import java.util.Map;
public class RedisTableData extends AbstractParameterTableData {
private static final FunctionProcessor REDIS = new AbstractFunctionProcessor() {
@Override
public int getId() {
return FunctionHelper.generateFunctionID(RedisConstants.PLUGIN_ID);
}
@Override
public String getLocaleKey() {
return "Plugin-Redis_DB";
}
@Override
public String toString() {
return Inter.getLocText("Plugin-Redis_DB");
}
};
private Connection database;
private OrderValue dbIndex;
private String query;
public void setDatabase(Connection c) {
this.database = c;
}
public Connection getDatabase() {
return database;
}
public OrderValue getOrderValue() {
return dbIndex;
}
public void setOrderValue(OrderValue dbIndex) {
this.dbIndex = dbIndex;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public void setParameters(ParameterProvider[] providers) {
super.setDefaultParameters(providers);
}
@Override
public DataModel createDataModel(Calculator calculator) {
return createDataModel(calculator, TableData.RESULT_ALL);
}
@Override
public DataModel createDataModel(Calculator calculator, int rowCount) {
FunctionProcessor processor = ExtraClassManager.getInstance().getFunctionProcessor();
if (processor != null) {
processor.recordFunction(REDIS);
}
Parameter[] ps = Parameter.providers2Parameter(getParameters(calculator));
if (database instanceof NameDatabaseConnection) {
String name = ((NameDatabaseConnection) database).getName();
RedisDatabaseConnection rc = DatasourceManager.getProviderInstance().getConnection(name, RedisDatabaseConnection.class);
if (rc != null) {
return new RedisTableDataModel(calculator, ps, rc,
dbIndex == null ? 0 : dbIndex.toIndex(calculator, ps),
calculateQuery(query, ps),
rowCount);
}
}
return null;
}
private String calculateQuery(String query, Parameter[] ps) {
if (ArrayUtils.isEmpty(ps)) {
return query;
}
Map<String, Object> map = new HashMap<String, Object>();
for (Parameter p : ps) {
map.put(p.getName(), p.getValue());
}
try {
return TemplateUtils.renderParameter4Tpl(query, map);
} catch (Exception e) {
return query;
}
}
public void readXML(XMLableReader reader) {
super.readXML(reader);
if (reader.isChildNode()) {
String tmpName = reader.getTagName();
String tmpVal;
if (OrderValue.XML_TAG.equals(tmpName)) {
this.dbIndex = (OrderValue) GeneralXMLTools.readXMLable(reader);
} else if (com.fr.data.impl.Connection.XML_TAG.equals(tmpName)) {
if (reader.getAttrAsString("class", null) != null) {
com.fr.data.impl.Connection con = DataCoreXmlUtils.readXMLConnection(reader);
this.setDatabase(con);
}
} else if ("Query".equals(tmpName)) {
tmpVal = reader.getElementValue();
if (isNotNullValue(tmpVal)) {
this.setQuery(tmpVal);
}
}
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
super.writeXML(writer);
GeneralXMLTools.writeXMLable(writer, dbIndex, OrderValue.XML_TAG);
if (this.database != null) {
DataCoreXmlUtils.writeXMLConnection(writer, this.database);
}
writer.startTAG("Query").textNode(getQuery()).end();
}
private boolean isNotNullValue(String value) {
return value != null && !"null".equals(value);
}
@Override
public Object clone() throws CloneNotSupportedException {
RedisTableData cloned = (RedisTableData) super.clone();
cloned.database = (Connection) database.clone();
cloned.query = query;
cloned.dbIndex = dbIndex;
return cloned;
}
}

89
src/main/java/com/fr/plugin/db/redis/core/RedisTableDataModel.java

@ -0,0 +1,89 @@
package com.fr.plugin.db.redis.core;
import com.fr.base.FRContext;
import com.fr.base.Parameter;
import com.fr.data.AbstractDataModel;
import com.fr.general.FRLogger;
import com.fr.general.data.TableDataException;
import com.fr.plugin.PluginLicense;
import com.fr.plugin.PluginLicenseManager;
import com.fr.plugin.db.redis.core.visit.VisitorFactory;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import redis.clients.jedis.Jedis;
import java.util.*;
public class RedisTableDataModel extends AbstractDataModel {
private Jedis redisClient;
private String[] columnNames;
private List<List<Object>> data;
public RedisTableDataModel(Calculator calculator, Parameter[] ps, RedisDatabaseConnection mc, int dbIndex, String query, int rowCount) {
PluginLicense pluginLicense = PluginLicenseManager.getInstance().getPluginLicenseByID(RedisConstants.PLUGIN_ID);
if (pluginLicense.isAvailable()) {
initRedisData(calculator, ps, mc, dbIndex, query, rowCount);
} else {
throw new RuntimeException("Redis Plugin License Expired!");
}
}
private synchronized void initRedisData(Calculator calculator, Parameter[] ps, RedisDatabaseConnection mc, int dbIndex, String query, int rowCount) {
if (StringUtils.isEmpty(query)) {
return;
}
if (redisClient == null) {
redisClient = mc.createRedisClient();
redisClient.select(dbIndex);
FRContext.getLogger().info("Connect to redis and select database:" + dbIndex);
}
try {
DataWrapper<Object> wrapper = VisitorFactory.getKeyValueResult(calculator, ps, redisClient, query, rowCount);
data = wrapper.getData();
columnNames = wrapper.getColumnNames();
} catch (Exception e) {
throw new RuntimeException(e.getCause());
}
}
@Override
public int getColumnCount() throws TableDataException {
return columnNames.length;
}
@Override
public String getColumnName(int columnIndex) throws TableDataException {
return columnNames[columnIndex];
}
@Override
public boolean hasRow(int rowIndex) throws TableDataException {
return data != null && data.get(0).size() > rowIndex;
}
@Override
public int getRowCount() throws TableDataException {
return data == null ? 0 : data.get(0).size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) throws TableDataException {
if (data != null && data.size() > columnIndex) {
List<Object> columnData = data.get(columnIndex);
if (columnData != null && columnData.size() > rowIndex) {
return columnData.get(rowIndex);
}
}
return null;
}
@Override
public void release() throws Exception {
if (redisClient != null) {
redisClient.quit();
redisClient = null;
}
}
}

48
src/main/java/com/fr/plugin/db/redis/core/order/OrderValue.java

@ -0,0 +1,48 @@
package com.fr.plugin.db.redis.core.order;
import com.fr.base.Parameter;
import com.fr.general.GeneralUtils;
import com.fr.script.Calculator;
import com.fr.stable.ParameterProvider;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLable;
import com.fr.stable.xml.XMLableReader;
public abstract class OrderValue implements XMLable {
private static final long serialVersionUID = -5421898153556627638L;
public static final String XML_TAG = "OrderValue";
public abstract Object getValue();
public abstract int toIndex(Calculator cal, Parameter[] ps);
public ParameterProvider[] analyze4Parameters() {
return new ParameterProvider[0];
}
@Override
public void readXML(XMLableReader reader) {
if (reader.isChildNode()) {
String tagName = reader.getTagName();
if ("Attr".equals(tagName)) {
readValue(reader);
}
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
writer.startTAG("Attr");
writer.attr("value", GeneralUtils.objectToString(getValue()));
writer.end();
}
public abstract void readValue(XMLableReader reader);
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

69
src/main/java/com/fr/plugin/db/redis/core/order/impl/FormulaOrderValue.java

@ -0,0 +1,69 @@
package com.fr.plugin.db.redis.core.order.impl;
import com.fr.base.BaseFormula;
import com.fr.base.FRContext;
import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.base.ParameterMapNameSpace;
import com.fr.general.GeneralUtils;
import com.fr.plugin.db.redis.core.order.OrderValue;
import com.fr.script.Calculator;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.UtilEvalError;
import com.fr.stable.script.NameSpace;
import com.fr.stable.xml.XMLableReader;
public class FormulaOrderValue extends OrderValue {
private BaseFormula formula;
public FormulaOrderValue() {
}
public FormulaOrderValue(BaseFormula formula) {
this.formula = formula;
}
public void setValue(BaseFormula formula) {
this.formula = formula;
}
@Override
public BaseFormula getValue() {
return formula;
}
@Override
public int toIndex(Calculator cal, Parameter[] ps) {
NameSpace nameSpace = ParameterMapNameSpace.create(ps);
cal.pushNameSpace(nameSpace);
try {
return GeneralUtils.objectToNumber(formula.eval(cal)).intValue();
} catch (UtilEvalError u) {
FRContext.getLogger().error(u.getMessage(), u);
} finally {
cal.removeNameSpace(nameSpace);
}
return 0;
}
@Override
public ParameterProvider[] analyze4Parameters() {
if (formula == null) {
return new ParameterProvider[0];
}
return ParameterHelper.analyze4ParametersFromFormula(formula.getContent());
}
@Override
public void readValue(XMLableReader reader) {
this.formula = BaseFormula.createFormulaBuilder().build(reader.getAttrAsString("value", StringUtils.EMPTY));
}
@Override
public String toString() {
return formula == null ? StringUtils.EMPTY : formula.getPureContent();
}
}

40
src/main/java/com/fr/plugin/db/redis/core/order/impl/NumberOrderValue.java

@ -0,0 +1,40 @@
package com.fr.plugin.db.redis.core.order.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.order.OrderValue;
import com.fr.script.Calculator;
import com.fr.stable.xml.XMLableReader;
public class NumberOrderValue extends OrderValue {
private static final long serialVersionUID = -7086244583348467452L;
private int value;
public NumberOrderValue() {
}
public NumberOrderValue(int value) {
this.value = value;
}
@Override
public Integer getValue() {
return value;
}
@Override
public int toIndex(Calculator cal, Parameter[] ps) {
return getValue();
}
@Override
public void readValue(XMLableReader reader) {
this.value = reader.getAttrAsInt("value", 0);
}
@Override
public String toString() {
return value + "";
}
}

28
src/main/java/com/fr/plugin/db/redis/core/visit/AbstractVisitor.java

@ -0,0 +1,28 @@
package com.fr.plugin.db.redis.core.visit;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.DataWrapper;
import com.fr.plugin.db.redis.core.RedisConstants;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import redis.clients.jedis.Jedis;
/**
* Created by richie on 2017/5/2.
*/
public abstract class AbstractVisitor<T> implements Visitor<T> {
@Override
public DataWrapper<T> buildData(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
return DataWrapper.create(getContent(calculator, ps, client, query, rowCount), RedisConstants.DEFAULT_COLUMN_NAMES);
}
@Override
public boolean match(String query) {
return query.trim().toLowerCase().startsWith(keyWord());
}
protected String trimCommand(String cmd) {
return StringUtils.trim(cmd);
}
}

25
src/main/java/com/fr/plugin/db/redis/core/visit/Visitor.java

@ -0,0 +1,25 @@
package com.fr.plugin.db.redis.core.visit;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.DataWrapper;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import redis.clients.jedis.Jedis;
import java.util.List;
/**
* Created by richie on 2017/5/2.
*/
public interface Visitor<T> {
String TOKEN_SPACE = "\\s+";
List<List<T>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception;
DataWrapper<T> buildData(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception;
boolean match(String query);
String keyWord();
}

50
src/main/java/com/fr/plugin/db/redis/core/visit/VisitorFactory.java

@ -0,0 +1,50 @@
package com.fr.plugin.db.redis.core.visit;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.DataWrapper;
import com.fr.plugin.db.redis.core.visit.impl.*;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
/**
* Created by richie on 2017/5/2.
*/
public class VisitorFactory {
private static List<Visitor> visitors = new ArrayList<Visitor>();
static {
visitors.add(new GetVisitor());
visitors.add(new ListVisitor());
visitors.add(new HashVisitor());
visitors.add(new HashGetVisitor());
visitors.add(new HashMGetVisitor());
visitors.add(new HashKeysVisitor());
visitors.add(new SetVisitor());
visitors.add(new ZRangeVisitor());
visitors.add(new MGetVisitor());
visitors.add(new KeysVisitor());
visitors.add(new SingleArrayVisitor());
}
public static <T> DataWrapper<T> getKeyValueResult(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
Visitor visitor = getMatchedVisitor(query);
if (visitor == null) {
return DataWrapper.EMPTY;
} else {
return visitor.buildData(calculator, ps, client, query, rowCount);
}
}
private static Visitor getMatchedVisitor(String query) {
for (Visitor visitor : visitors) {
if (visitor.match(query)) {
return visitor;
}
}
return null;
}
}

32
src/main/java/com/fr/plugin/db/redis/core/visit/impl/GetVisitor.java

@ -0,0 +1,32 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
public class GetVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 2) {
throw new IllegalArgumentException("Illegal query:" + query);
}
String data = client.get(trimCommand(arr[1]));
List<String> column = new ArrayList<String>();
column.add(data);
List<List<String>> result = new ArrayList<List<String>>();
result.add(column);
result.add(column);
return result;
}
@Override
public String keyWord() {
return "get";
}
}

32
src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashGetVisitor.java

@ -0,0 +1,32 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
public class HashGetVisitor extends AbstractVisitor <String>{
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 3) {
throw new IllegalArgumentException("Illegal query:" + query);
}
String data = client.hget(trimCommand(arr[1]), trimCommand(arr[2]));
List<String> column = new ArrayList<String>();
column.add(data);
List<List<String>> result = new ArrayList<List<String>>();
result.add(column);
result.add(column);
return result;
}
@Override
public String keyWord() {
return "hget";
}
}

32
src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashKeysVisitor.java

@ -0,0 +1,32 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class HashKeysVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 2) {
throw new IllegalArgumentException("Illegal query:" + query);
}
Set<String> data = client.hkeys(trimCommand(arr[1]));
List<String> column = new ArrayList<String>(data);
List<List<String>> result = new ArrayList<List<String>>();
result.add(column);
result.add(column);
return result;
}
@Override
public String keyWord() {
return "hkeys";
}
}

35
src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashMGetVisitor.java

@ -0,0 +1,35 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
public class HashMGetVisitor extends AbstractVisitor<String>{
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 3) {
throw new IllegalArgumentException("Illegal query:" + query);
}
List<String> keys = new ArrayList<String>();
for (int i = 2, len = arr.length; i < len; i ++) {
keys.add(trimCommand(arr[i]));
}
String[] fields = keys.toArray(new String[keys.size()]);
List<String> data = client.hmget(trimCommand(arr[1]), fields);
List<List<String>> result = new ArrayList<List<String>>();
result.add(keys);
result.add(data);
return result;
}
@Override
public String keyWord() {
return "hmget";
}
}

39
src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashVisitor.java

@ -0,0 +1,39 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by richie on 2017/5/2.
*/
public class HashVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 2) {
throw new IllegalArgumentException("Illegal query:" + query);
}
Map<String, String> map = client.hgetAll(trimCommand(arr[1]));
List<String> column1 = new ArrayList<String>();
List<String> column2 = new ArrayList<String>();
for (Map.Entry<String, String> entry : map.entrySet()) {
column1.add(entry.getKey());
column2.add(entry.getValue());
}
List<List<String>> result = new ArrayList<List<String>>();
result.add(column1);
result.add(column2);
return result;
}
@Override
public String keyWord() {
return "hgetall";
}
}

32
src/main/java/com/fr/plugin/db/redis/core/visit/impl/KeysVisitor.java

@ -0,0 +1,32 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class KeysVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 2) {
throw new IllegalArgumentException("Illegal query:" + query);
}
Set<String> data = client.keys(trimCommand(arr[1]));
List<String> column = new ArrayList<String>(data);
List<List<String>> result = new ArrayList<List<String>>();
result.add(column);
result.add(column);
return result;
}
@Override
public String keyWord() {
return "keys";
}
}

39
src/main/java/com/fr/plugin/db/redis/core/visit/impl/ListVisitor.java

@ -0,0 +1,39 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.base.TableData;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
/**
* Created by richie on 2017/5/2.
*/
public class ListVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 4) {
throw new IllegalArgumentException("Illegal query:" + query);
}
long start = Long.parseLong(trimCommand(arr[2]));
long end = Long.parseLong(trimCommand(arr[3]));
if (rowCount != TableData.RESULT_ALL) {
end = start + rowCount;
}
List<String> data = client.lrange(arr[1], start, end);
List<List<String>> result = new ArrayList<List<String>>();
result.add(data);
result.add(data);
return result;
}
@Override
public String keyWord() {
return "lrange";
}
}

34
src/main/java/com/fr/plugin/db/redis/core/visit/impl/MGetVisitor.java

@ -0,0 +1,34 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
/**
* Created by richie on 2017/5/3.
*/
public class MGetVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 2) {
throw new IllegalArgumentException("Illegal query:" + query);
}
String[] args = (String[]) ArrayUtils.remove(arr, 0);
List<String> data = client.mget(args);
List<List<String>> result = new ArrayList<List<String>>();
result.add(data);
result.add(data);
return result;
}
@Override
public String keyWord() {
return "mget";
}
}

38
src/main/java/com/fr/plugin/db/redis/core/visit/impl/SetVisitor.java

@ -0,0 +1,38 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Created by richie on 2017/5/2.
*/
public class SetVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 2) {
throw new IllegalArgumentException("Illegal query:" + query);
}
Set<String> data = client.smembers(trimCommand(arr[1]));
List<String> column = new ArrayList<String>();
for (String element : data) {
column.add(element);
}
List<List<String>> result = new ArrayList<List<String>>();
result.add(column);
result.add(column);
return result;
}
@Override
public String keyWord() {
return "smembers";
}
}

91
src/main/java/com/fr/plugin/db/redis/core/visit/impl/SingleArrayVisitor.java

@ -0,0 +1,91 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.general.FRLogger;
import com.fr.plugin.db.redis.conf.ShellConfigManager;
import com.fr.plugin.db.redis.core.DataWrapper;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import redis.clients.jedis.Jedis;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Created by richie on 2017/6/5.
*/
public class SingleArrayVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (ArrayUtils.getLength(arr) < 1) {
throw new IllegalArgumentException("Illegal query:" + query);
}
String shell = ShellConfigManager.getProviderInstance().getShellText();
if (StringUtils.isNotEmpty(shell)) {
for (Parameter parameter : ps) {
shell += " " + parameter.getName() + " " + parameter.getValue();
}
Process process = Runtime.getRuntime().exec(shell);
String statusText = getShellResult(process);
if (isSuccess(statusText)) {
return calculateData(client, arr[1]);
}
}
return null;
}
@Override
public String keyWord() {
return "singlemaparray";
}
private boolean isSuccess(String statusText) {
return "success".equals(statusText);
}
// TODO:richie 只要实现这个方法就可以了,还要处理列名的时候,需要修改下面 buildData方法
private List<List<String>> calculateData(Jedis client, String key) {
String result = client.get(key);
return null;
}
@Override
public DataWrapper<String> buildData(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
return super.buildData(calculator, ps, client, query, rowCount);
}
private String getShellResult(Process process) {
String result = null;
try {
ByteArrayOutputStream resultOutStream = new ByteArrayOutputStream();
InputStream errorInStream = new BufferedInputStream(process.getErrorStream());
InputStream processInStream = new BufferedInputStream(process.getInputStream());
int num = 0;
byte[] bs = new byte[1024];
while ((num = errorInStream.read(bs)) != -1) {
resultOutStream.write(bs, 0, num);
}
while ((num = processInStream.read(bs)) != -1) {
resultOutStream.write(bs, 0, num);
}
result = new String(resultOutStream.toByteArray());
errorInStream.close();
processInStream.close();
resultOutStream.close();
} catch (IOException e) {
FRLogger.getLogger().error(e.getMessage(), e);
} finally {
if (process != null) {
process.destroy();
}
}
return result;
}
}

46
src/main/java/com/fr/plugin/db/redis/core/visit/impl/ZRangeVisitor.java

@ -0,0 +1,46 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.base.TableData;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Created by richie on 2017/5/2.
*/
public class ZRangeVisitor extends AbstractVisitor<Object> {
@Override
public List<List<Object>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (arr.length < 4) {
throw new IllegalArgumentException("Illegal query:" + query);
}
long start = Long.parseLong(trimCommand(arr[2]));
long end = Long.parseLong(trimCommand(arr[3]));
if (rowCount != TableData.RESULT_ALL) {
end = start + rowCount;
}
Set<Tuple> data = client.zrangeWithScores(trimCommand(arr[1]), start, end);
List<Object> column = new ArrayList<Object>();
List<Object> value = new ArrayList<Object>();
for (Tuple element : data) {
column.add(element.getElement());
value.add(element.getScore());
}
List<List<Object>> result = new ArrayList<List<Object>>();
result.add(column);
result.add(value);
return result;
}
@Override
public String keyWord() {
return "zrange";
}
}

80
src/main/java/com/fr/plugin/db/redis/ui/RedisConnectionPane.java

@ -0,0 +1,80 @@
package com.fr.plugin.db.redis.ui;
import com.fr.design.border.UITitledBorder;
import com.fr.design.data.datapane.connect.DatabaseConnectionPane;
import com.fr.design.gui.ibutton.UIPasswordField;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UIIntNumberField;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.general.Inter;
import com.fr.plugin.db.redis.core.RedisDatabaseConnection;
import javax.swing.*;
import java.awt.*;
public class RedisConnectionPane extends DatabaseConnectionPane<com.fr.plugin.db.redis.core.RedisDatabaseConnection> {
private UITextField hostTextField;
private UIIntNumberField portNumberField;
private UIPasswordField passwordTextField;
@Override
protected JPanel mainPanel() {
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
hostTextField = new UITextField();
portNumberField = new UIIntNumberField();
passwordTextField = new UIPasswordField();
Component[][] components = new Component[][]{
{new UILabel(Inter.getLocText("Plugin-Redis_Host") + ":"), hostTextField},
{new UILabel(Inter.getLocText("Plugin-Redis_Port") + ":"), portNumberField},
{new UILabel(Inter.getLocText("Plugin-Redis_Password") + ":"), passwordTextField}
};
double p = TableLayout.PREFERRED;
double[] rowSize = new double[]{p, p, p, p};
double[] columnSize = new double[]{p, 400};
JPanel settingsUI = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize);
settingsUI.setBorder(UITitledBorder.createBorderWithTitle("Redis"));
JPanel centerPane = FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane();
centerPane.add(settingsUI);
pane.add(centerPane, BorderLayout.CENTER);
return pane;
}
@Override
protected boolean isFineBI() {
return false;
}
@Override
protected void populateSubDatabaseConnectionBean(RedisDatabaseConnection ob) {
hostTextField.setText(ob.getHost());
portNumberField.setValue(ob.getPort());
passwordTextField.setText(ob.getPassword());
}
@Override
protected com.fr.plugin.db.redis.core.RedisDatabaseConnection updateSubDatabaseConnectionBean() {
RedisDatabaseConnection connection = new RedisDatabaseConnection();
connection.setHost(hostTextField.getText());
connection.setPort((int) portNumberField.getValue());
connection.setPassword(passwordTextField.getText());
return connection;
}
@Override
protected String title4PopupWindow() {
return "Redis";
}
}

143
src/main/java/com/fr/plugin/db/redis/ui/RedisDBConnectionChosePane.java

@ -0,0 +1,143 @@
package com.fr.plugin.db.redis.ui;
import com.fr.base.FRContext;
import com.fr.data.impl.Connection;
import com.fr.design.data.datapane.connect.ConnectionComboBoxPanel;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itextfield.PlaceholderTextField;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.file.DatasourceManager;
import com.fr.general.Inter;
import com.fr.plugin.db.redis.ui.event.DataLoadedListener;
import com.fr.plugin.db.redis.core.RedisDatabaseConnection;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
public class RedisDBConnectionChosePane extends BasicPane {
private ConnectionComboBoxPanel connectionComboBoxPanel;
private DefaultListModel listModel = new DefaultListModel();
private List<DataLoadedListener> listeners = new ArrayList<DataLoadedListener>();
private PlaceholderTextField keysPatternTextField;
public RedisDBConnectionChosePane() {
setLayout(new BorderLayout(4, 4));
connectionComboBoxPanel = new ConnectionComboBoxPanel(Connection.class) {
protected void filterConnection(Connection connection, String conName, List<String> nameList) {
connection.addConnection(nameList, conName, new Class[]{RedisDatabaseConnection.class});
}
};
add(connectionComboBoxPanel, BorderLayout.NORTH);
connectionComboBoxPanel.addComboBoxActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadKeys();
}
});
JList list = new JList(listModel);
keysPatternTextField = new PlaceholderTextField(10);
keysPatternTextField.setPlaceholder(Inter.getLocText("Plugin-Redis_Keys_Pattern"));
JPanel centerPane = new JPanel(new BorderLayout());
UIButton searchButton = new UIButton(Inter.getLocText("Plugin-Redis_Keys_Pattern_Search"));
searchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadKeys();
}
});
centerPane.add(GUICoreUtils.createBorderLayoutPane(
keysPatternTextField, BorderLayout.CENTER,
searchButton, BorderLayout.EAST), BorderLayout.NORTH);
centerPane.add(list, BorderLayout.CENTER);
add(centerPane, BorderLayout.CENTER);
}
private void loadKeys() {
String name = getSelectRedisConnectionName();
if (StringUtils.isEmpty(name)) {
clearList();
fireDataLoaded(ArrayUtils.EMPTY_STRING_ARRAY);
return;
}
RedisDatabaseConnection connection = DatasourceManager.getProviderInstance().getConnection(name, RedisDatabaseConnection.class);
if (connection != null) {
listMatchedPatternKeys(connection);
}
}
private void clearList() {
listModel.clear();
}
private void listMatchedPatternKeys(final RedisDatabaseConnection connection) {
clearList();
new SwingWorker<String[], Void>() {
@Override
protected String[] doInBackground() throws Exception {
String keysPattern = keysPatternTextField.getText();
if (StringUtils.isEmpty(keysPattern)) {
return ArrayUtils.EMPTY_STRING_ARRAY;
} else {
Set<String> keys = connection.createRedisClient().keys(keysPattern);
return keys.toArray(new String[keys.size()]);
}
}
@Override
protected void done() {
try {
String[] keys = get();
for (String name : keys) {
listModel.addElement(name);
}
fireDataLoaded(keys);
} catch (Exception e) {
FRContext.getLogger().error(e.getMessage(), e);
}
}
}.execute();
}
public String getSelectRedisConnectionName() {
return connectionComboBoxPanel.getSelectedItem();
}
public void populateConnection(Connection connection) {
connectionComboBoxPanel.populate(connection);
}
public void addDataLoadedListener(DataLoadedListener listener) {
listeners.add(listener);
}
private void fireDataLoaded(String[] data) {
for (DataLoadedListener listener : listeners) {
listener.fireEvent(data);
}
}
@Override
protected String title4PopupWindow() {
return "Choose";
}
}

94
src/main/java/com/fr/plugin/db/redis/ui/RedisQueryPane.java

@ -0,0 +1,94 @@
package com.fr.plugin.db.redis.ui;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.editor.ValueEditorPane;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.FRLogger;
import com.fr.general.Inter;
import com.fr.general.SiteCenter;
import com.fr.plugin.db.redis.core.order.OrderValue;
import com.fr.plugin.db.redis.ui.value.IndexValuePaneFactory;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
public class RedisQueryPane extends BasicPane {
private SQLEditPane sqlTextPane;
private ValueEditorPane dbIndexEditor;
public RedisQueryPane() {
setLayout(new BorderLayout());
sqlTextPane = new SQLEditPane();
dbIndexEditor = IndexValuePaneFactory.createValueEditorPane();
ActionLabel helpLabel = new ActionLabel(Inter.getLocText("Plugin-Redis_Help"));
helpLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().browse(URI.create(SiteCenter.getInstance().acquireUrlByKind("help.redis")));
} catch (IOException e1) {
FRLogger.getLogger().error(e1.getMessage(), e1);
}
}
});
Component[][] coms = new Component[][]{
{new UILabel(Inter.getLocText("Plugin-Redis_DB_Index") + ":"), dbIndexEditor},
{GUICoreUtils.createBorderLayoutPane(new UILabel(Inter.getLocText("Plugin-Redis_Query_Condition") + ":"), BorderLayout.NORTH), createConditionTextPane(sqlTextPane)}
};
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p, p};
double[] columnSize = {p, f};
add(TableLayoutHelper.createTableLayoutPane(coms, rowSize, columnSize));
}
private RTextScrollPane createConditionTextPane(SQLEditPane sqlTextPane) {
sqlTextPane.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL);
RTextScrollPane sqlTextScrollPane = new RTextScrollPane(sqlTextPane);
sqlTextScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
sqlTextScrollPane.setPreferredSize(new Dimension(680, 300));
return sqlTextScrollPane;
}
@Override
protected String title4PopupWindow() {
return "Query";
}
public String getQuery() {
return sqlTextPane.getText();
}
public void setQuery(String query) {
sqlTextPane.setText(query);
}
public OrderValue getOrderValue() {
return (OrderValue) dbIndexEditor.update();
}
public void setOrderValue(OrderValue orderValue) {
dbIndexEditor.populate(orderValue);
}
}

209
src/main/java/com/fr/plugin/db/redis/ui/RedisTableDataPane.java

@ -0,0 +1,209 @@
package com.fr.plugin.db.redis.ui;
import com.fr.base.BaseUtils;
import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.design.actions.UpdateAction;
import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.gui.itableeditorpane.ParameterTableModel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.menu.ToolBarDef;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.plugin.db.redis.core.RedisTableData;
import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class RedisTableDataPane extends AbstractTableDataPane<RedisTableData> {
private static final String PREVIEW_BUTTON = Inter.getLocText("Preview");
private static final String REFRESH_BUTTON = Inter.getLocText("Refresh");
private RedisDBConnectionChosePane chosePane;
private UITableEditorPane<ParameterProvider> editorPane;
private RedisQueryPane queryPane;
public RedisTableDataPane() {
this.setLayout(new BorderLayout(4, 4));
Box box = new Box(BoxLayout.Y_AXIS);
queryPane = new RedisQueryPane();
JPanel northPane = new JPanel(new BorderLayout(4, 4));
JToolBar editToolBar = createToolBar();
northPane.add(editToolBar, BorderLayout.CENTER);
northPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));
ParameterTableModel model = new ParameterTableModel() {
@Override
public UITableEditAction[] createAction() {
return ArrayUtils.add(super.createDBTableAction(), new RefreshAction());
}
};
editorPane = new UITableEditorPane<ParameterProvider>(model);
box.add(northPane);
box.add(queryPane);
box.add(editorPane);
JPanel sqlSplitPane = new JPanel(new BorderLayout(4, 4));
sqlSplitPane.add(box, BorderLayout.CENTER);
chosePane = new RedisDBConnectionChosePane();
chosePane.setPreferredSize(new Dimension(200, 200));
sqlSplitPane.add(chosePane, BorderLayout.WEST);
this.add(sqlSplitPane, BorderLayout.CENTER);
}
private boolean isPreviewOrRefreshButton(FocusEvent e) {
if (e.getOppositeComponent() != null) {
String name = e.getOppositeComponent().getName();
return ComparatorUtils.equals(name, PREVIEW_BUTTON) || ComparatorUtils.equals(name, REFRESH_BUTTON);
}
return false;
}
private JToolBar createToolBar() {
ToolBarDef toolBarDef = new ToolBarDef();
toolBarDef.addShortCut(new PreviewAction());
UIToolbar editToolBar = ToolBarDef.createJToolBar();
toolBarDef.updateToolBar(editToolBar);
return editToolBar;
}
@Override
protected String title4PopupWindow() {
return Inter.getLocText("DS-Database_Query");
}
private void refresh() {
String[] paramTexts = new String[]{queryPane.getQuery()};
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false);
ParameterProvider[] providers = queryPane.getOrderValue().analyze4Parameters();
editorPane.populate(ArrayUtils.addAll(parameters, providers));
}
private void checkParameter() {
String[] paramTexts = new String[]{queryPane.getQuery()};
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false);
parameters = ArrayUtils.addAll(parameters, queryPane.getOrderValue().analyze4Parameters());
if (parameters.length < 1 && editorPane.update().size() < 1) {
return;
}
boolean isIn = true;
List<ParameterProvider> list = editorPane.update();
List<String> name = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
name.add(list.get(i).getName());
}
for (int i = 0; i < parameters.length; i++) {
if (!name.contains(parameters[i].getName())) {
isIn = false;
break;
}
}
if (list.size() == parameters.length && isIn) {
return;
}
refresh();
}
@Override
public void populateBean(RedisTableData tableData) {
if (tableData == null) {
return;
}
Calculator c = Calculator.createCalculator();
editorPane.populate(tableData.getParameters(c));
chosePane.populateConnection(tableData.getDatabase());
queryPane.setQuery(tableData.getQuery());
queryPane.setOrderValue(tableData.getOrderValue());
}
@Override
public RedisTableData updateBean() {
RedisTableData tableData = new RedisTableData();
String connectionName = chosePane.getSelectRedisConnectionName();
if (StringUtils.isNotEmpty(connectionName)) {
tableData.setDatabase(new NameDatabaseConnection(connectionName));
}
List<ParameterProvider> parameterList = editorPane.update();
ParameterProvider[] parameters = parameterList.toArray(new ParameterProvider[parameterList.size()]);
tableData.setParameters(parameters);
tableData.setQuery(queryPane.getQuery());
tableData.setOrderValue(queryPane.getOrderValue());
return tableData;
}
private class PreviewAction extends UpdateAction {
public PreviewAction() {
this.setName(PREVIEW_BUTTON);
this.setMnemonic('P');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/preview.png"));
}
public void actionPerformed(ActionEvent evt) {
checkParameter();
PreviewTablePane.previewTableData(RedisTableDataPane.this.updateBean());
}
}
protected class RefreshAction extends UITableEditAction {
public RefreshAction() {
this.setName(REFRESH_BUTTON);
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/control/refresh.png"));
}
public void actionPerformed(ActionEvent e) {
refresh();
}
@Override
public void checkEnabled() {
}
}
}

6
src/main/java/com/fr/plugin/db/redis/ui/event/DataLoadedListener.java

@ -0,0 +1,6 @@
package com.fr.plugin.db.redis.ui.event;
public interface DataLoadedListener {
void fireEvent(String[] data);
}

142
src/main/java/com/fr/plugin/db/redis/ui/value/FormulaEditor.java

@ -0,0 +1,142 @@
package com.fr.plugin.db.redis.ui.value;
import com.fr.base.BaseFormula;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.editor.editor.Editor;
import com.fr.design.formula.FormulaFactory;
import com.fr.design.formula.UIFormula;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.plugin.db.redis.core.order.impl.FormulaOrderValue;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class FormulaEditor extends Editor<FormulaOrderValue> {
private UITextField currentTextField;
private FormulaEditor.ShowPaneListener listener = new FormulaEditor.ShowPaneListener();
private FormulaOrderValue orderValue = new FormulaOrderValue(BaseFormula.createFormulaBuilder().build());
/**
* Constructor.
*/
public FormulaEditor() {
this("公式");
}
public FormulaEditor(String name) {
this(name, null);
}
public FormulaEditor(String name, FormulaOrderValue formula) {
if (formula != null) {
this.orderValue = formula;
}
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel editPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
currentTextField = new UITextField(28);
currentTextField.setText(this.orderValue.getValue().getContent());
editPane.add(currentTextField, BorderLayout.CENTER);
currentTextField.setEditable(false);
currentTextField.addMouseListener(listener);
this.add(editPane, BorderLayout.CENTER);
this.setName(name);
}
private class ShowPaneListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if (currentTextField.isEnabled()) {
showFormulaPane();
}
}
}
public void setColumns(int i) {
this.currentTextField.setColumns(i);
}
/**
* 选中时弹出公式编辑框
*/
public void selected() {
showFormulaPane();
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
currentTextField.setEnabled(enabled);
}
protected void showFormulaPane() {
final UIFormula formulaPane = FormulaFactory.createFormulaPaneWhenReserveFormula();
formulaPane.populate(orderValue.getValue());
formulaPane.showLargeWindow(SwingUtilities.getWindowAncestor(FormulaEditor.this), new DialogActionAdapter() {
@Override
public void doOk() {
orderValue.setValue(formulaPane.update());
setValue(orderValue);
fireStateChanged();
}
}).setVisible(true);
}
/**
* Return the value of the CellEditor.
*/
@Override
public FormulaOrderValue getValue() {
return orderValue;
}
/**
* Set the value to the CellEditor.
*/
@Override
public void setValue(FormulaOrderValue value) {
if (value == null) {
value = new FormulaOrderValue(BaseFormula.createFormulaBuilder().build());
}
this.orderValue = value;
currentTextField.setText(value.toString());
}
public String getIconName() {
return "type_formula";
}
/**
* object是否是公司类型对象
*
* @param object 需判断的对象
* @return 是公式类型则返回true
*/
public boolean accept(Object object) {
return object instanceof FormulaOrderValue;
}
/**
* 重置
*/
public void reset() {
currentTextField.setText("=");
orderValue = new FormulaOrderValue(BaseFormula.createFormulaBuilder().build());
}
/**
* 清楚数据
*/
public void clearData() {
reset();
}
}

20
src/main/java/com/fr/plugin/db/redis/ui/value/IndexValuePaneFactory.java

@ -0,0 +1,20 @@
package com.fr.plugin.db.redis.ui.value;
import com.fr.design.editor.ValueEditorPane;
import com.fr.design.editor.ValueEditorPaneFactory;
import com.fr.design.editor.editor.Editor;
public class IndexValuePaneFactory {
/**
* 创建带编辑器的ValueEditorPane
*
* @return 返回pane
*/
public static ValueEditorPane createValueEditorPane() {
return ValueEditorPaneFactory.createValueEditorPane(new Editor[]{
new IntegerEditor(),
new FormulaEditor()
});
}
}

114
src/main/java/com/fr/plugin/db/redis/ui/value/IntegerEditor.java

@ -0,0 +1,114 @@
package com.fr.plugin.db.redis.ui.value;
import com.fr.base.Utils;
import com.fr.design.editor.editor.Editor;
import com.fr.design.gui.itextfield.UIIntNumberField;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.plugin.db.redis.core.order.impl.NumberOrderValue;
import com.fr.stable.StringUtils;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class IntegerEditor extends Editor<NumberOrderValue> {
private static final long serialVersionUID = 1L;
protected UIIntNumberField numberField; // text field.
protected String oldValue = StringUtils.EMPTY;
/**
* Constructor.
*/
public IntegerEditor() {
this(null, "序号");
}
/**
* Constructor.
*/
public IntegerEditor(NumberOrderValue value, String name) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
numberField = new UIIntNumberField();
this.add(numberField, BorderLayout.CENTER);
this.numberField.addKeyListener(textKeyListener);
this.numberField.setHorizontalAlignment(UITextField.RIGHT);
this.setValue(value);
this.setName(name);
}
public void setColumns(int columns) {
this.numberField.setColumns(columns);
}
public int getHorizontalAlignment() {
return this.numberField.getHorizontalAlignment();
}
public void setHorizontalAlignment(int horizontalAlignment) {
this.numberField.setHorizontalAlignment(horizontalAlignment);
}
public void setEnabled(boolean enabled) {
this.numberField.setEnabled(enabled);
}
public void selected() {
this.requestFocus();
}
public String getIconName() {
return "type_double";
}
public void requestFocus() {
this.numberField.requestFocus();
}
KeyListener textKeyListener = new KeyAdapter() {
public void keyReleased(KeyEvent evt) {
int code = evt.getKeyCode();
if (code == KeyEvent.VK_ESCAPE) {
numberField.setText(oldValue);
}
if (code == KeyEvent.VK_ENTER) {
fireEditingStopped();
} else {
fireStateChanged();
}
}
};
@Override
public NumberOrderValue getValue() {
return new NumberOrderValue((int)this.numberField.getValue());
}
@Override
public void setValue(NumberOrderValue value) {
if (value == null) {
value = new NumberOrderValue(0);
}
this.numberField.setValue(value.getValue());
oldValue = Utils.objectToString(value);
}
@Override
public boolean accept(Object object) {
return object != null && object instanceof NumberOrderValue;
}
}

BIN
src/main/resources/com/fr/plugin/db/redis/images/redis.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

10
src/main/resources/com/fr/plugin/db/redis/locale/redis.properties

@ -0,0 +1,10 @@
Plugin-Redis_Host=Host
Plugin-Redis_Port=Port
Plugin-Redis_Password=Password
Plugin-Redis_Table_Data=Redis Table Data
Plugin-Redis_Query_Condition=Query Condition
Plugin-Redis_DB=RedisDB
Plugin-Redis_Help=Help Doc
Plugin-Redis_Keys_Pattern=Keys Pattern
Plugin-Redis_Keys_Pattern_Search=Search
Plugin-Redis_DB_Index=DB Index

10
src/main/resources/com/fr/plugin/db/redis/locale/redis_en_US.properties

@ -0,0 +1,10 @@
Plugin-Redis_Host=Host
Plugin-Redis_Port=Port
Plugin-Redis_Password=Password
Plugin-Redis_Table_Data=Redis
Plugin-Redis_Query_Condition=Query Condition
Plugin-Redis_DB=RedisDB
Plugin-Redis_Help=Help Doc
Plugin-Redis_Keys_Pattern=Keys Pattern
Plugin-Redis_Keys_Pattern_Search=Search
Plugin-Redis_DB_Index=DB Index

10
src/main/resources/com/fr/plugin/db/redis/locale/redis_zh_CN.properties

@ -0,0 +1,10 @@
Plugin-Redis_Host=\u6570\u636E\u5E93\u5730\u5740
Plugin-Redis_Port=\u7AEF\u53E3
Plugin-Redis_Password=\u5BC6\u7801
Plugin-Redis_Table_Data=Redis\u6570\u636E\u96C6
Plugin-Redis_Query_Condition=\u67E5\u8BE2\u6761\u4EF6
Plugin-Redis_DB=RedisDB\u6570\u636E\u96C6
Plugin-Redis_Help=\u5E2E\u52A9\u6587\u6863
Plugin-Redis_Keys_Pattern=\u952E\u503C\u7684\u6B63\u5219\u8868\u8FBE\u5F0F
Plugin-Redis_Keys_Pattern_Search=\u641C\u7D22
Plugin-Redis_DB_Index=\u6570\u636E\u5E93\u7F16\u53F7
Loading…
Cancel
Save