alex.sung
6 years ago
36 changed files with 585 additions and 798 deletions
@ -1,120 +0,0 @@
|
||||
package com.fr.design.extra.ucenter; |
||||
|
||||
import com.fr.base.Base64; |
||||
import com.fr.base.FRContext; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import java.io.UnsupportedEncodingException; |
||||
import java.net.URLEncoder; |
||||
import java.security.MessageDigest; |
||||
import java.security.NoSuchAlgorithmException; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author lp |
||||
* @date 2016/9/9 |
||||
*/ |
||||
public abstract class AbstractClient { |
||||
|
||||
static final String UC_API_MYSQL = "ucApiMysql"; |
||||
static final String UC_API_POST = "ucApiPost"; |
||||
|
||||
protected String urlEncode(String value) { |
||||
return URLEncoder.encode(value); |
||||
} |
||||
|
||||
protected String md5(String input) { |
||||
MessageDigest md; |
||||
try { |
||||
md = MessageDigest.getInstance("MD5"); |
||||
} catch (NoSuchAlgorithmException e) { |
||||
FRContext.getLogger().info(e.getMessage()); |
||||
return ""; |
||||
} |
||||
return byte2hex(md.digest(input.getBytes())); |
||||
} |
||||
|
||||
protected String md5(long input) { |
||||
return md5(String.valueOf(input)); |
||||
} |
||||
|
||||
protected String base64Decode(String input) { |
||||
try { |
||||
return new String(Base64.decode(input)); |
||||
} catch (Exception e) { |
||||
FRContext.getLogger().info(e.getMessage()); |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
protected String base64Encode(String input) { |
||||
try { |
||||
return Base64.encode(input.getBytes("iso-8859-1")); |
||||
} catch (Exception e) { |
||||
FRContext.getLogger().info(e.getMessage()); |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
protected String byte2hex(byte[] b) { |
||||
StringBuilder hs = new StringBuilder(); |
||||
String stmp = ""; |
||||
for (byte aB : b) { |
||||
stmp = (Integer.toHexString(aB & 0XFF)); |
||||
if (stmp.length() == 1) { |
||||
hs.append("0").append(stmp); |
||||
} else { |
||||
hs.append(stmp); |
||||
} |
||||
} |
||||
return hs.toString(); |
||||
} |
||||
|
||||
protected String subStr(String input, int begin, int length) { |
||||
return input.substring(begin, begin + length); |
||||
} |
||||
|
||||
protected String subStr(String input, int begin) { |
||||
if (begin > 0) { |
||||
return input.substring(begin); |
||||
} else { |
||||
return input.substring(input.length() + begin); |
||||
} |
||||
} |
||||
|
||||
protected long microTime() { |
||||
return System.currentTimeMillis(); |
||||
} |
||||
|
||||
protected long time() { |
||||
return System.currentTimeMillis() / 1000; |
||||
} |
||||
|
||||
protected String sprintf(String format, long input) { |
||||
String temp = "0000000000" + input; |
||||
return temp.substring(temp.length() - 10); |
||||
} |
||||
|
||||
protected String callUserFunc(String function, String model, String action, Map<String, Object> args) { |
||||
if (UC_API_MYSQL.equals(function)) { |
||||
return this.ucApiMysql(model, action, args); |
||||
} |
||||
if (UC_API_POST.equals(function)) { |
||||
return this.ucApiPost(model, action, args); |
||||
} |
||||
return StringUtils.EMPTY; |
||||
} |
||||
|
||||
public abstract String ucApiPost(String module, String action, Map<String, Object> arg); |
||||
|
||||
public abstract String ucApiMysql(String model, String action, Map args); |
||||
|
||||
protected String urlEncode(String value, String code) { |
||||
try { |
||||
return URLEncoder.encode(value, code); |
||||
} catch (UnsupportedEncodingException e) { |
||||
FRContext.getLogger().info(e.getMessage()); |
||||
} |
||||
return ""; |
||||
} |
||||
} |
@ -1,264 +0,0 @@
|
||||
package com.fr.design.extra.ucenter; |
||||
|
||||
import com.fr.base.FRContext; |
||||
import com.fr.general.CloudCenter; |
||||
|
||||
import java.io.BufferedReader; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.InputStreamReader; |
||||
import java.io.OutputStream; |
||||
import java.net.Socket; |
||||
import java.net.URL; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
|
||||
/** |
||||
* |
||||
* @author lp |
||||
* @date 2016/9/9 |
||||
*/ |
||||
public class Client extends AbstractClient { |
||||
|
||||
private static String UC_IP = ""; |
||||
private static String UC_API = ""; |
||||
private static String UC_CONNECT = ""; |
||||
private static String UC_KEY = "Rc85U37411p4zdvcedm8D4t4D3l9Sa42H0kd98Gbd82aA99a61S2Z5LbQ9u430M0"; |
||||
private static String UC_APPID = "4"; |
||||
private static String UC_CLIENT_RELEASE = "20090212"; |
||||
public static String UC_ROOT = ""; |
||||
private static String UC_API_FUNC = "mysql".equals(UC_CONNECT) ? UC_API_MYSQL : UC_API_POST; |
||||
|
||||
public String ucUserLogin(String username, String password) { |
||||
return ucUserLogin(username, password, 0, 0); |
||||
} |
||||
|
||||
public String ucUserLogin(String username, String password, int isUid, int checkQues) { |
||||
return ucUserLogin(username, password, isUid, checkQues, "", ""); |
||||
} |
||||
|
||||
/** |
||||
* 用户登录 |
||||
* |
||||
* @param username 用户名 |
||||
* @param password 密码 |
||||
* @param isUid 是否为uid |
||||
* @param checkQues 是否使用安全问题 |
||||
* @param questionId 安全提问 |
||||
* @param answer 安全提问答案 |
||||
* @return array (uid/status, username, password, email) |
||||
*/ |
||||
public String ucUserLogin(String username, String password, int isUid, int checkQues, String questionId, String answer) { |
||||
Map<String, Object> args = new HashMap<>(6); |
||||
args.put("username", username); |
||||
args.put("password", password); |
||||
args.put("isUid", isUid); |
||||
args.put("checkQues", checkQues); |
||||
args.put("questionId", questionId); |
||||
args.put("answer", answer); |
||||
String res = callUserFunc(UC_API_FUNC, "user", "login", args); |
||||
return "mysql".equals(UC_CONNECT) ? res : res; |
||||
} |
||||
|
||||
/** |
||||
* 拼接发送的post请求 |
||||
* |
||||
* @param module 模块 |
||||
* @param action 操作模式 |
||||
* @param arg 参数 |
||||
* @return 发送的请求加密内容 |
||||
*/ |
||||
@Override |
||||
public String ucApiPost(String module, String action, Map<String, Object> arg) { |
||||
StringBuilder str = new StringBuilder(); |
||||
String sep = ""; |
||||
for (String k : arg.keySet()) { |
||||
Object v = arg.get(k); |
||||
k = urlEncode(k); |
||||
if (v.getClass().isAssignableFrom(Map.class)) { |
||||
StringBuilder s2 = new StringBuilder(); |
||||
String sep2 = ""; |
||||
for (String k2 : ((Map<String, Object>) v).keySet()) { |
||||
Object v2 = ((Map<String, Object>) v).get(k2); |
||||
k2 = urlEncode(k2); |
||||
s2.append(sep2).append("{").append(k).append("}[").append(k2).append("]=").append(urlEncode(String.valueOf(v2))); |
||||
sep2 = "&"; |
||||
} |
||||
str.append(sep).append(s2); |
||||
} else { |
||||
str.append(sep).append(k).append("=").append(urlEncode(String.valueOf(v), "GBK")); |
||||
} |
||||
sep = "&"; |
||||
} |
||||
String postData = ucApiRequestdata(module, action, str.toString(), ""); |
||||
UC_API = CloudCenter.getInstance().acquireUrlByKind("bbs.ucapi"); |
||||
UC_IP = CloudCenter.getInstance().acquireUrlByKind("bbs.ip"); |
||||
return ucFopen2(UC_API + "/index.php", 500000, postData, "", true, UC_IP, 20, true); |
||||
} |
||||
|
||||
@Override |
||||
public String ucApiMysql(String model, String action, Map args) { |
||||
return ""; |
||||
} |
||||
|
||||
public String ucApiInput(String data) { |
||||
return urlEncode(ucAuthCode(data + "&agent=" + md5("") + "&time=" + time(), "ENCODE", UC_KEY), "GBK"); |
||||
} |
||||
|
||||
protected String ucApiRequestdata(String module, String action, String arg, String extra) { |
||||
String input = ucApiInput(arg); |
||||
return "m=" + module + "&a=" + action + "&inajax=2&release=" + UC_CLIENT_RELEASE + "&input=" + input + "&appid=" + UC_APPID + extra; |
||||
} |
||||
|
||||
public String ucAuthCode(String string, String operation, String key) { |
||||
return ucAuthCode(string, operation, key, 0); |
||||
} |
||||
|
||||
/** |
||||
* 内容加密 |
||||
* |
||||
* @param string 原文 |
||||
* @param operation decode或者encode |
||||
* @param key 密钥 |
||||
* @param expiry 密文有效时限 |
||||
* @return 加密之后的原文 |
||||
*/ |
||||
public String ucAuthCode(String string, String operation, String key, int expiry) { |
||||
int ckeyLength = 4; |
||||
key = md5(key != null ? key : UC_KEY); |
||||
String keya = md5(subStr(key, 0, 16)); |
||||
String keyb = md5(subStr(key, 16, 16)); |
||||
String keyc = "DECODE".equals(operation) ? subStr(string, 0, ckeyLength) : subStr(md5(microTime()), -ckeyLength); |
||||
String cryptkey = keya + md5(keya + keyc); |
||||
int keyLength = cryptkey.length(); |
||||
string = "DECODE".equals(operation) ? base64Decode(subStr(string, ckeyLength)) : sprintf("%010d", expiry > 0 ? expiry + time() : 0) + subStr(md5(string + keyb), 0, 16) + string; |
||||
int stringLength = string.length(); |
||||
StringBuilder result1 = new StringBuilder(); |
||||
int[] box = new int[256]; |
||||
for (int i = 0; i < 256; i++) { |
||||
box[i] = i; |
||||
} |
||||
int[] rndkey = new int[256]; |
||||
for (int i = 0; i <= 255; i++) { |
||||
rndkey[i] = (int) cryptkey.charAt(i % keyLength); |
||||
} |
||||
int j = 0; |
||||
for (int i = 0; i < 256; i++) { |
||||
j = (j + box[i] + rndkey[i]) % 256; |
||||
int tmp = box[i]; |
||||
box[i] = box[j]; |
||||
box[j] = tmp; |
||||
} |
||||
j = 0; |
||||
int a = 0; |
||||
for (int i = 0; i < stringLength; i++) { |
||||
a = (a + 1) % 256; |
||||
j = (j + box[a]) % 256; |
||||
int tmp = box[a]; |
||||
box[a] = box[j]; |
||||
box[j] = tmp; |
||||
result1.append((char) (((int) string.charAt(i)) ^ (box[(box[a] + box[j]) % 256]))); |
||||
} |
||||
if ("DECODE".equals(operation)) { |
||||
String result = result1.toString(); |
||||
try { |
||||
result = new String(result.getBytes("iso-8859-1"), "gbk"); |
||||
} catch (Exception e) { |
||||
result = result1.substring(0, result1.length()); |
||||
} |
||||
if ((Integer.parseInt(subStr(result, 0, 10)) == 0 || Long.parseLong(subStr(result, 0, 10)) - time() > 0) && subStr(result, 10, 16).equals(subStr(md5(subStr(result, 26) + keyb), 0, 16))) { |
||||
return subStr(result, 26); |
||||
} else { |
||||
return ""; |
||||
} |
||||
} else { |
||||
return keyc + base64Encode(result1.toString()).replaceAll("=", ""); |
||||
} |
||||
} |
||||
|
||||
protected String ucFopen2(String url, int limit, String post, String cookie, boolean bysocket, String ip, int timeout, boolean block) { |
||||
url += url.indexOf("?") > 0 ? "&" : "?" + "__times__=1"; |
||||
return ucFopen(url, limit, post, cookie, bysocket, ip, timeout, block); |
||||
} |
||||
|
||||
/** |
||||
* 本地模网络请求取数据 |
||||
* |
||||
* @param url 打开的url |
||||
* @param limit 取返回的数据的长度 |
||||
* @param post 要发送的 POST 数据,如uid=1&password=1234 |
||||
* @param cookie 要模拟的 COOKIE 数据,如uid=123&auth=a2323sd2323 |
||||
* @param bysocket TRUE/FALSE 是否通过SOCKET打开 |
||||
* @param ip IP地址 |
||||
* @param timeout 连接超时时间 |
||||
* @param block 是否为阻塞模式 defaul valuet:true |
||||
* @return 取到的字符串 |
||||
*/ |
||||
private String ucFopen(String url, int limit, String post, String cookie, boolean bysocket, String ip, int timeout, boolean block) { |
||||
StringBuilder result = new StringBuilder(); |
||||
URL matches; |
||||
String host = ""; |
||||
String path = ""; |
||||
int port = 80; |
||||
try { |
||||
matches = new URL(url); |
||||
host = matches.getHost(); |
||||
path = matches.getPath() != null ? matches.getPath() + (matches.getQuery() != null ? "?" + matches.getQuery() : "") : "/"; |
||||
if (matches.getPort() > 0) port = matches.getPort(); |
||||
} catch (Exception e1) { |
||||
FRContext.getLogger().info(e1.getMessage()); |
||||
} |
||||
StringBuilder out = new StringBuilder(); |
||||
if (post != null && post.length() > 0) { |
||||
out.append("POST ").append(path).append(" HTTP/1.0\r\n"); |
||||
out.append("Accept: */*\r\n"); |
||||
out.append("Accept-Language: zh-cn\r\n"); |
||||
out.append("Content-Type: application/x-www-form-urlencoded\r\n"); |
||||
out.append("User-Agent: \r\n"); |
||||
out.append("Host: ").append(host).append("\r\n"); |
||||
out.append("Content-Length: ").append(post.length()).append("\r\n"); |
||||
out.append("Connection: Close\r\n"); |
||||
out.append("Cache-Control: no-cache\r\n"); |
||||
out.append("Cookie: \r\n\r\n"); |
||||
out.append(post); |
||||
} else { |
||||
out.append("GET $path HTTP/1.0\r\n"); |
||||
out.append("Accept: */*\r\n"); |
||||
out.append("Accept-Language: zh-cn\r\n"); |
||||
out.append("User-Agent: Java/1.5.0_01\r\n"); |
||||
out.append("Host: $host\r\n"); |
||||
out.append("Connection: Close\r\n"); |
||||
out.append("Cookie: $cookie\r\n\r\n"); |
||||
} |
||||
try { |
||||
Socket fp = new Socket(ip != null && ip.length() > 10 ? ip : host, port); |
||||
if (!fp.isConnected()) { |
||||
return ""; |
||||
} else { |
||||
OutputStream os = fp.getOutputStream(); |
||||
os.write(out.toString().getBytes()); |
||||
InputStream ins = fp.getInputStream(); |
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(ins, "iso-8859-1")); |
||||
while (true) { |
||||
String header = reader.readLine(); |
||||
if (header == null || "".equals(header) || Objects.equals(header, "\r\n") || Objects.equals(header, "\n")) { |
||||
break; |
||||
} |
||||
} |
||||
while (true) { |
||||
String data = reader.readLine(); |
||||
if (data == null || "".equals(data)) { |
||||
break; |
||||
} else { |
||||
result.append(data); |
||||
} |
||||
} |
||||
fp.close(); |
||||
} |
||||
} catch (IOException e) { |
||||
FRContext.getLogger().info(e.getMessage()); |
||||
} |
||||
return result.toString(); |
||||
} |
||||
} |
@ -1,41 +0,0 @@
|
||||
package com.fr.design.extra.ucenter; |
||||
|
||||
import com.fr.base.FRContext; |
||||
import com.sun.org.apache.xerces.internal.parsers.DOMParser; |
||||
import org.w3c.dom.Document; |
||||
import org.w3c.dom.NodeList; |
||||
import org.xml.sax.InputSource; |
||||
import org.xml.sax.SAXException; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.StringReader; |
||||
import java.util.LinkedList; |
||||
|
||||
/** |
||||
* @author lp |
||||
* @date 2016/9/9 |
||||
*/ |
||||
public class XMLHelper { |
||||
|
||||
public static LinkedList<String> ucUnserialize(String input) { |
||||
|
||||
LinkedList<String> result = new LinkedList<String>(); |
||||
DOMParser parser = new DOMParser(); |
||||
try { |
||||
parser.parse(new InputSource(new StringReader(input))); |
||||
Document doc = parser.getDocument(); |
||||
NodeList nl = doc.getChildNodes().item(0).getChildNodes(); |
||||
int length = nl.getLength(); |
||||
for (int i = 0; i < length; i++) { |
||||
if (nl.item(i).getNodeType() == Document.ELEMENT_NODE) { |
||||
result.add(nl.item(i).getTextContent()); |
||||
} |
||||
} |
||||
} catch (SAXException e) { |
||||
FRContext.getLogger().info(e.getMessage()); |
||||
} catch (IOException e1) { |
||||
FRContext.getLogger().info(e1.getLocalizedMessage()); |
||||
} |
||||
return result; |
||||
} |
||||
} |
@ -0,0 +1,55 @@
|
||||
package com.fr.design.fun; |
||||
|
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.designer.TargetComponent; |
||||
import com.fr.design.gui.imenu.UIPopupMenu; |
||||
import com.fr.design.mainframe.BaseFormDesigner; |
||||
import com.fr.design.selection.SelectableElement; |
||||
import com.fr.stable.fun.mark.Mutable; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 设计器右键菜单接口 |
||||
*/ |
||||
public interface RightSelectionHandlerProvider extends Mutable { |
||||
|
||||
int CURRENT_LEVEL = 1; |
||||
|
||||
String XML_TAG = "RightSelectionHandlerProvider"; |
||||
|
||||
|
||||
/** |
||||
* 对单元格或者悬浮元素的右键菜单项进行增删改 |
||||
* |
||||
* @param ePane 选择的元素 |
||||
* @param popupMenu 右键主菜单 |
||||
*/ |
||||
void dmlMenu(TargetComponent ePane, UIPopupMenu popupMenu); |
||||
|
||||
|
||||
/** |
||||
* 当前实现是否可以作用于当前元素 |
||||
* |
||||
* @param selectableElement 当前选中元素分为CellSelection和FloatSelection(单元格和悬浮元素) |
||||
* @return |
||||
*/ |
||||
boolean accept(SelectableElement selectableElement); |
||||
|
||||
|
||||
/** |
||||
* 对表单,参数面板内置的右键选项进行增删改处理 |
||||
* |
||||
* @param actions 默认的action集合 注意:主体代码要求这边的action必须是UndoableAction 的子类而非updateAction |
||||
*/ |
||||
void dmlUpdateActions(BaseFormDesigner formDesigner, List<UpdateAction> actions); |
||||
|
||||
/** |
||||
* 当前实现是否可以作用于当前元素 |
||||
* |
||||
* @param formDesigner 当前选中元素分为表单编辑器和参数面板(表单组件元素以及各种控件) |
||||
* @return |
||||
*/ |
||||
boolean accept(BaseFormDesigner formDesigner); |
||||
|
||||
} |
@ -0,0 +1,45 @@
|
||||
package com.fr.design.fun.impl; |
||||
|
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.designer.TargetComponent; |
||||
import com.fr.design.fun.RightSelectionHandlerProvider; |
||||
import com.fr.design.gui.imenu.UIPopupMenu; |
||||
import com.fr.design.mainframe.BaseFormDesigner; |
||||
import com.fr.design.selection.SelectableElement; |
||||
import com.fr.stable.fun.impl.AbstractProvider; |
||||
import com.fr.stable.fun.mark.API; |
||||
|
||||
import java.util.List; |
||||
|
||||
@API(level = RightSelectionHandlerProvider.CURRENT_LEVEL) |
||||
public abstract class AbstractRightSelectionHandlerProvider extends AbstractProvider implements RightSelectionHandlerProvider { |
||||
@Override |
||||
public int currentAPILevel() { |
||||
return CURRENT_LEVEL; |
||||
} |
||||
|
||||
@Override |
||||
public String mark4Provider() { |
||||
return getClass().getName(); |
||||
} |
||||
|
||||
@Override |
||||
public void dmlUpdateActions(BaseFormDesigner formDesigner, List<UpdateAction> actions) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public boolean accept(BaseFormDesigner formDesigner) { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public void dmlMenu(TargetComponent ePane, UIPopupMenu popupMenu) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public boolean accept(SelectableElement selectableElement) { |
||||
return false; |
||||
} |
||||
} |
@ -0,0 +1,40 @@
|
||||
package com.fr.design.formula; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import static junit.framework.Assert.fail; |
||||
import static junit.framework.TestCase.assertEquals; |
||||
import static junit.framework.TestCase.assertTrue; |
||||
|
||||
/** |
||||
* Created by plough on 2018/12/7. |
||||
*/ |
||||
public class FunctionConstantsTest { |
||||
@Test |
||||
public void testNewInstanceFail() throws Exception { |
||||
try { |
||||
FunctionConstants.class.newInstance(); |
||||
fail("Not allowed to instantiate FunctionConstants!"); |
||||
} catch (IllegalAccessException e) { |
||||
assertTrue(true); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testEmbedFuntionsAfterStaticInit() { |
||||
NameAndTypeAndFunctionList[] embFunctionLists = FunctionConstants.EMBFUNCTIONS; |
||||
// 一共有 8 个分类
|
||||
assertEquals(8, embFunctionLists.length); |
||||
for (NameAndTypeAndFunctionList embFunctionsList : embFunctionLists) { |
||||
// 每个分类下都有函数
|
||||
NameAndDescription[] nameAndDescriptions = embFunctionsList.getDescriptions(); |
||||
assertTrue(nameAndDescriptions.length > 0); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testCommonFuntionsAfterStaticInit() { |
||||
NameAndFunctionList commonFunctionList = FunctionConstants.COMMON; |
||||
assertEquals(9, commonFunctionList.getDescriptions().length); |
||||
} |
||||
} |
Loading…
Reference in new issue