commit b787d0897e37aacf1673d61cdb40ee3f972d20bd Author: richie Date: Thu Nov 15 14:10:11 2018 +0800 数据库/数据集插件示例 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..991a9d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.iml +.idea/ +lib/report/*.jar +target/ +.DS_Store \ No newline at end of file diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..94a72d5 --- /dev/null +++ b/build.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/jedis-2.9.0.jar b/lib/jedis-2.9.0.jar new file mode 100644 index 0000000..f4d27d3 Binary files /dev/null and b/lib/jedis-2.9.0.jar differ diff --git a/lib/report/.gitkepp b/lib/report/.gitkepp new file mode 100644 index 0000000..e69de29 diff --git a/plugin.xml b/plugin.xml new file mode 100755 index 0000000..89c8d91 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,29 @@ + + + com.fr.solution.plugin.db.redis.v10 + + yes + 3.0 + 10.0 + 2018-08-20 + richie + + + [2018-05-12]增加了keys、hget、hmget、hkeys查询。
+ [2018-05-11]增加连接错误判定。
+ [2018-03-30]增加数据库编号选择。
+ [2017-04-18]连接Redis数据库。
+ ]]>
+ + + + + + + + + + + +
\ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..667c936 --- /dev/null +++ b/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + + com.fr.plugin + starter + 10.0 + + jar + demo-tabledata-redis + + + ${project.basedir}/../webroot/WEB-INF/plugins/plugin-com.fr.solution.plugin.db.redis.v10-1.0/classes + + + org.apache.maven.plugins + maven-compiler-plugin + + 6 + 6 + + + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..135033b --- /dev/null +++ b/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中注册即可。 + + diff --git a/screenshots/1.png b/screenshots/1.png new file mode 100644 index 0000000..5ec4ac6 Binary files /dev/null and b/screenshots/1.png differ diff --git a/screenshots/2.png b/screenshots/2.png new file mode 100644 index 0000000..894846b Binary files /dev/null and b/screenshots/2.png differ diff --git a/screenshots/3.png b/screenshots/3.png new file mode 100644 index 0000000..862407a Binary files /dev/null and b/screenshots/3.png differ diff --git a/src/main/java/com/fr/plugin/db/redis/RedisConnectionImpl.java b/src/main/java/com/fr/plugin/db/redis/RedisConnectionImpl.java new file mode 100755 index 0000000..a28166d --- /dev/null +++ b/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 classForConnection() { + return RedisDatabaseConnection.class; + } + + @Override + public Class> appearanceForConnection() { + return RedisConnectionPane.class; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/RedisLocaleFinder.java b/src/main/java/com/fr/plugin/db/redis/RedisLocaleFinder.java new file mode 100755 index 0000000..ccb1218 --- /dev/null +++ b/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"; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/RedisTableDataDefine.java b/src/main/java/com/fr/plugin/db/redis/RedisTableDataDefine.java new file mode 100755 index 0000000..2ac1286 --- /dev/null +++ b/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 classForTableData() { + return RedisTableData.class; + } + + @Override + public Class classForInitTableData() { + return RedisTableData.class; + } + + @Override + public Class 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"; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManager.java b/src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManager.java new file mode 100644 index 0000000..40218b8 --- /dev/null +++ b/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(); + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManagerProvider.java b/src/main/java/com/fr/plugin/db/redis/conf/ShellConfigManagerProvider.java new file mode 100644 index 0000000..ac07e56 --- /dev/null +++ b/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(); +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/DataWrapper.java b/src/main/java/com/fr/plugin/db/redis/core/DataWrapper.java new file mode 100644 index 0000000..7d79bf6 --- /dev/null +++ b/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 { + + public static DataWrapper create(List> data, String[] columnNames) { + return new DataWrapper(data, columnNames); + } + + public static DataWrapper EMPTY = new DataWrapper(null, RedisConstants.DEFAULT_COLUMN_NAMES); + + private List> data; + private String[] columnNames; + + private DataWrapper(List> data, String[] columnNames) { + this.data = data; + this.columnNames = columnNames; + } + + public String[] getColumnNames() { + if (columnNames == null) { + return RedisConstants.DEFAULT_COLUMN_NAMES; + } + return columnNames; + } + + public List> getData() { + return data; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/RedisConstants.java b/src/main/java/com/fr/plugin/db/redis/core/RedisConstants.java new file mode 100755 index 0000000..a1cb729 --- /dev/null +++ b/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"}; +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/RedisDatabaseConnection.java b/src/main/java/com/fr/plugin/db/redis/core/RedisDatabaseConnection.java new file mode 100755 index 0000000..1ea1213 --- /dev/null +++ b/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 list, String connectionName, Class[] acceptTypes) { + for (Class 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; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/core/RedisMechanism.java b/src/main/java/com/fr/plugin/db/redis/core/RedisMechanism.java new file mode 100755 index 0000000..3cecad5 --- /dev/null +++ b/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; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/RedisTableData.java b/src/main/java/com/fr/plugin/db/redis/core/RedisTableData.java new file mode 100755 index 0000000..f078d41 --- /dev/null +++ b/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 map = new HashMap(); + 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; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/core/RedisTableDataModel.java b/src/main/java/com/fr/plugin/db/redis/core/RedisTableDataModel.java new file mode 100755 index 0000000..a13eb33 --- /dev/null +++ b/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> 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 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 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; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/core/order/OrderValue.java b/src/main/java/com/fr/plugin/db/redis/core/order/OrderValue.java new file mode 100644 index 0000000..04ffe79 --- /dev/null +++ b/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(); + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/order/impl/FormulaOrderValue.java b/src/main/java/com/fr/plugin/db/redis/core/order/impl/FormulaOrderValue.java new file mode 100644 index 0000000..97b09a2 --- /dev/null +++ b/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(); + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/order/impl/NumberOrderValue.java b/src/main/java/com/fr/plugin/db/redis/core/order/impl/NumberOrderValue.java new file mode 100644 index 0000000..1d90912 --- /dev/null +++ b/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 + ""; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/AbstractVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/AbstractVisitor.java new file mode 100644 index 0000000..2d6bf36 --- /dev/null +++ b/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 implements Visitor { + + @Override + public DataWrapper 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); + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/Visitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/Visitor.java new file mode 100644 index 0000000..53f1898 --- /dev/null +++ b/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 { + + String TOKEN_SPACE = "\\s+"; + + List> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception; + + DataWrapper buildData(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception; + + boolean match(String query); + + String keyWord(); +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/VisitorFactory.java b/src/main/java/com/fr/plugin/db/redis/core/visit/VisitorFactory.java new file mode 100644 index 0000000..41a6bce --- /dev/null +++ b/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 visitors = new ArrayList(); + + 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 DataWrapper 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; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/GetVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/GetVisitor.java new file mode 100644 index 0000000..281104e --- /dev/null +++ b/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 { + @Override + public List> 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 column = new ArrayList(); + column.add(data); + + List> result = new ArrayList>(); + result.add(column); + result.add(column); + return result; + } + + @Override + public String keyWord() { + return "get"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashGetVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashGetVisitor.java new file mode 100644 index 0000000..e6fb36c --- /dev/null +++ b/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 { + @Override + public List> 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 column = new ArrayList(); + column.add(data); + + List> result = new ArrayList>(); + result.add(column); + result.add(column); + return result; + } + + @Override + public String keyWord() { + return "hget"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashKeysVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashKeysVisitor.java new file mode 100644 index 0000000..bf6b21a --- /dev/null +++ b/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 { + @Override + public List> 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 data = client.hkeys(trimCommand(arr[1])); + List column = new ArrayList(data); + + List> result = new ArrayList>(); + result.add(column); + result.add(column); + return result; + } + + @Override + public String keyWord() { + return "hkeys"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashMGetVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashMGetVisitor.java new file mode 100644 index 0000000..73f5549 --- /dev/null +++ b/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{ + @Override + public List> 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 keys = new ArrayList(); + for (int i = 2, len = arr.length; i < len; i ++) { + keys.add(trimCommand(arr[i])); + } + String[] fields = keys.toArray(new String[keys.size()]); + List data = client.hmget(trimCommand(arr[1]), fields); + + List> result = new ArrayList>(); + result.add(keys); + result.add(data); + return result; + } + + @Override + public String keyWord() { + return "hmget"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/HashVisitor.java new file mode 100644 index 0000000..0ed4e07 --- /dev/null +++ b/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 { + @Override + public List> 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 map = client.hgetAll(trimCommand(arr[1])); + List column1 = new ArrayList(); + List column2 = new ArrayList(); + for (Map.Entry entry : map.entrySet()) { + column1.add(entry.getKey()); + column2.add(entry.getValue()); + } + List> result = new ArrayList>(); + result.add(column1); + result.add(column2); + return result; + } + + @Override + public String keyWord() { + return "hgetall"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/KeysVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/KeysVisitor.java new file mode 100644 index 0000000..aff98d7 --- /dev/null +++ b/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 { + @Override + public List> 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 data = client.keys(trimCommand(arr[1])); + List column = new ArrayList(data); + + List> result = new ArrayList>(); + result.add(column); + result.add(column); + return result; + } + + @Override + public String keyWord() { + return "keys"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/ListVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/ListVisitor.java new file mode 100644 index 0000000..8010619 --- /dev/null +++ b/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 { + @Override + public List> 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 data = client.lrange(arr[1], start, end); + List> result = new ArrayList>(); + result.add(data); + result.add(data); + return result; + } + + @Override + public String keyWord() { + return "lrange"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/MGetVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/MGetVisitor.java new file mode 100644 index 0000000..5a21fc7 --- /dev/null +++ b/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 { + @Override + public List> 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 data = client.mget(args); + List> result = new ArrayList>(); + result.add(data); + result.add(data); + return result; + } + + @Override + public String keyWord() { + return "mget"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/SetVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/SetVisitor.java new file mode 100644 index 0000000..8d03314 --- /dev/null +++ b/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 { + + @Override + public List> 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 data = client.smembers(trimCommand(arr[1])); + List column = new ArrayList(); + for (String element : data) { + column.add(element); + } + List> result = new ArrayList>(); + result.add(column); + result.add(column); + return result; + } + + @Override + public String keyWord() { + return "smembers"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/SingleArrayVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/SingleArrayVisitor.java new file mode 100644 index 0000000..c001ad1 --- /dev/null +++ b/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 { + @Override + public List> 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> calculateData(Jedis client, String key) { + String result = client.get(key); + return null; + } + + @Override + public DataWrapper 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; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/core/visit/impl/ZRangeVisitor.java b/src/main/java/com/fr/plugin/db/redis/core/visit/impl/ZRangeVisitor.java new file mode 100644 index 0000000..b58725e --- /dev/null +++ b/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 { + @Override + public List> 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 data = client.zrangeWithScores(trimCommand(arr[1]), start, end); + List column = new ArrayList(); + List value = new ArrayList(); + for (Tuple element : data) { + column.add(element.getElement()); + value.add(element.getScore()); + } + List> result = new ArrayList>(); + result.add(column); + result.add(value); + return result; + } + + @Override + public String keyWord() { + return "zrange"; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/ui/RedisConnectionPane.java b/src/main/java/com/fr/plugin/db/redis/ui/RedisConnectionPane.java new file mode 100755 index 0000000..40040c9 --- /dev/null +++ b/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 { + + 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"; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/ui/RedisDBConnectionChosePane.java b/src/main/java/com/fr/plugin/db/redis/ui/RedisDBConnectionChosePane.java new file mode 100755 index 0000000..7cee2b0 --- /dev/null +++ b/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 listeners = new ArrayList(); + private PlaceholderTextField keysPatternTextField; + + public RedisDBConnectionChosePane() { + setLayout(new BorderLayout(4, 4)); + connectionComboBoxPanel = new ConnectionComboBoxPanel(Connection.class) { + + protected void filterConnection(Connection connection, String conName, List 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() { + + @Override + protected String[] doInBackground() throws Exception { + String keysPattern = keysPatternTextField.getText(); + if (StringUtils.isEmpty(keysPattern)) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } else { + Set 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"; + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/ui/RedisQueryPane.java b/src/main/java/com/fr/plugin/db/redis/ui/RedisQueryPane.java new file mode 100755 index 0000000..ae726f7 --- /dev/null +++ b/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); + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/ui/RedisTableDataPane.java b/src/main/java/com/fr/plugin/db/redis/ui/RedisTableDataPane.java new file mode 100755 index 0000000..3ef3d2a --- /dev/null +++ b/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 { + private static final String PREVIEW_BUTTON = Inter.getLocText("Preview"); + private static final String REFRESH_BUTTON = Inter.getLocText("Refresh"); + + private RedisDBConnectionChosePane chosePane; + + private UITableEditorPane 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(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 list = editorPane.update(); + List name = new ArrayList(); + 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 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() { + } + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/ui/event/DataLoadedListener.java b/src/main/java/com/fr/plugin/db/redis/ui/event/DataLoadedListener.java new file mode 100755 index 0000000..86a18a2 --- /dev/null +++ b/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); +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/ui/value/FormulaEditor.java b/src/main/java/com/fr/plugin/db/redis/ui/value/FormulaEditor.java new file mode 100644 index 0000000..3846cf5 --- /dev/null +++ b/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 { + + 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(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/db/redis/ui/value/IndexValuePaneFactory.java b/src/main/java/com/fr/plugin/db/redis/ui/value/IndexValuePaneFactory.java new file mode 100644 index 0000000..abe3739 --- /dev/null +++ b/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() + }); + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/ui/value/IntegerEditor.java b/src/main/java/com/fr/plugin/db/redis/ui/value/IntegerEditor.java new file mode 100644 index 0000000..71a6fc0 --- /dev/null +++ b/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 { + 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; + } + +} \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/db/redis/images/redis.png b/src/main/resources/com/fr/plugin/db/redis/images/redis.png new file mode 100644 index 0000000..16cc883 Binary files /dev/null and b/src/main/resources/com/fr/plugin/db/redis/images/redis.png differ diff --git a/src/main/resources/com/fr/plugin/db/redis/locale/redis.properties b/src/main/resources/com/fr/plugin/db/redis/locale/redis.properties new file mode 100755 index 0000000..c2ee961 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/db/redis/locale/redis_en_US.properties b/src/main/resources/com/fr/plugin/db/redis/locale/redis_en_US.properties new file mode 100755 index 0000000..43a37b9 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/db/redis/locale/redis_zh_CN.properties b/src/main/resources/com/fr/plugin/db/redis/locale/redis_zh_CN.properties new file mode 100755 index 0000000..b35836e --- /dev/null +++ b/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 \ No newline at end of file