提交修改

This commit is contained in:
quyixiao 2021-01-21 18:03:03 +08:00
parent f24deffe00
commit 894fc29901
8 changed files with 492 additions and 0 deletions

View File

@ -0,0 +1,23 @@
package com.lz.common.cli;
public interface CliToken {
/**
* @return the token value
*/
String value();
/**
* @return the raw token value, that may contain unescaped chars, for instance {@literal "ab\"cd"}
*/
String raw();
/**
* @return true when it's a text token
*/
boolean isText();
/**
* @return true when it's a blank token
*/
boolean isBlank();
}

View File

@ -0,0 +1,43 @@
package com.lz.common.cli;
import com.lz.common.cli.impl.CliTokenImpl;
import java.util.List;
/**
* @author beiwei30 on 09/11/2016.
*/
public class CliTokens {
/**
* Create a text token.
*
* @param text the text
* @return the token
*/
public static CliToken createText(String text) {
return new CliTokenImpl(true, text, text);
}
/**
* Create a new blank token.
*
* @param blank the blank value
* @return the token
*/
public static CliToken createBlank(String blank) {
return new CliTokenImpl(false, blank, blank);
}
/**
* Tokenize the string argument and return a list of tokens.
*
* @param s the tokenized string
* @return the tokens
*/
public static List<CliToken> tokenize(String s) {
return CliTokenImpl.tokenize(s);
}
}

View File

@ -0,0 +1,8 @@
package com.lz.common.cli;
/**
* @author bw on 25/10/2016.
*/
public interface IntConsumer {
void accept(int value);
}

View File

@ -0,0 +1,160 @@
/*
* Copyright 2015 Julien Viet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lz.common.cli;
import java.util.LinkedList;
/**
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
*/
public class LineStatus implements IntConsumer {
// Keeping this internal to this package
static class Ext extends LineStatus implements IntConsumer {
final LinkedList<Integer> buffer;
Ext() {
this.buffer = new LinkedList<Integer>();
}
public void accept(int codePoint) {
super.accept(codePoint);
switch (transition) {
case TO_WEAK:
buffer.add((int) '"');
break;
case TO_STRONG:
buffer.add((int) '\'');
break;
case FROM_WEAK:
buffer.add((int) '"');
break;
case FROM_STRONG:
buffer.add((int) '\'');
break;
case TO_ESC:
buffer.add((int)'\\');
break;
case FROM_ESC:
if (codePoint != '\r') {
buffer.add(codePoint);
} else {
buffer.removeLast();
}
break;
case CODE_POINT:
buffer.add(codePoint);
break;
}
}
}
protected int quote = 0;
protected Transition transition;
public boolean isEscaped() {
return transition == Transition.FROM_ESC;
}
public boolean isEscaping() {
return transition == Transition.TO_ESC;
}
/**
* @return true if it's currently quoted
*/
public boolean isQuoted() {
return quote != 0;
}
public boolean isWeaklyQuoted() {
return quote == '"';
}
public boolean isStronglyQuoted() {
return quote == '\'';
}
/**
* @return the current quote: {@code 0}, {@code '} or {@code "} value
*/
public int getQuote() {
return quote;
}
public boolean isCodePoint() {
return transition == Transition.CODE_POINT || transition == Transition.FROM_ESC;
}
@Override
public void accept(int cp) {
Transition next;
if (transition == Transition.TO_ESC) {
next = Transition.FROM_ESC;
} else {
switch (quote) {
case 0:
switch (cp) {
case '\'':
quote = '\'';
next = Transition.TO_STRONG;
break;
case '"':
quote = '"';
next = Transition.TO_WEAK;
break;
case '\\':
next = Transition.TO_ESC;
break;
default:
next = Transition.CODE_POINT;
break;
}
break;
case '\'':
if (cp == '\'') {
quote = 0;
next = Transition.FROM_STRONG;
} else {
next = Transition.CODE_POINT;
}
break;
case '"':
if (cp == '"') {
quote = 0;
next = Transition.FROM_WEAK;
} else if (cp == '\\') {
// Note we don't make the distinction between special chars like " or \ from other chars
// that are supposed to not escaped (i.e "\a" is \a and "\$" is $)
// this interpretation is not done by termd
next = Transition.TO_ESC;
} else {
next = Transition.CODE_POINT;
}
break;
default:
throw new AssertionError();
}
}
this.transition = next;
}
private enum Transition {
TO_STRONG, TO_WEAK, FROM_STRONG, FROM_WEAK, TO_ESC, CODE_POINT, FROM_ESC;
}
}

View File

@ -0,0 +1,175 @@
package com.lz.common.cli.impl;
import com.lz.common.cli.CliToken;
import com.lz.common.cli.LineStatus;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
*/
public class CliTokenImpl implements CliToken {
final boolean text;
final String raw;
final String value;
public CliTokenImpl(boolean text, String value) {
this(text, value, value);
}
public CliTokenImpl(boolean text, String raw, String value) {
this.text = text;
this.raw = raw;
this.value = value;
}
@Override
public boolean isText() {
return text;
}
@Override
public boolean isBlank() {
return !text;
}
public String raw() {
return raw;
}
public String value() {
return value;
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj instanceof CliTokenImpl) {
CliTokenImpl that = (CliTokenImpl) obj;
return text == that.text && value.equals(that.value);
}
return false;
}
@Override
public String toString() {
return "CliToken[text=" + text + ",value=" + value + "]";
}
public static List<CliToken> tokenize(String s) {
List<CliToken> tokens = new LinkedList<CliToken>();
tokenize(s, 0, tokens);
return tokens;
}
private static void tokenize(String s, int index, List<CliToken> builder) {
while (index < s.length()) {
char c = s.charAt(index);
switch (c) {
case ' ':
case '\t':
index = blankToken(s, index, builder);
break;
case '(':
index = khToken(s, index, builder);
break;
default:
index = textToken(s, index, builder);
break;
}
}
}
// Todo use code points and not chars
private static int textToken(String s, int index, List<CliToken> builder) {
LineStatus quoter = new LineStatus();
int from = index;
StringBuilder value = new StringBuilder();
while (index < s.length()) {
char c = s.charAt(index);
if (isLeftKuo(c)) {
break;
}
quoter.accept(c);
if (!quoter.isQuoted() && !quoter.isEscaped() && isBlank(c)) {
break;
}
if (quoter.isCodePoint()) {
if (quoter.isEscaped() && quoter.isWeaklyQuoted() && c != '"') {
value.append('\\');
}
value.append(c);
}
index++;
}
builder.add(new CliTokenImpl(true, s.substring(from, index), value.toString()));
return index;
}
private static int blankToken(String s, int index, List<CliToken> builder) {
int from = index;
while (index < s.length() && isBlank(s.charAt(index))) {
index++;
}
// builder.add(new CliTokenImpl(false, s.substring(from, index)));
return index;
}
private static int khToken(String s, int index, List<CliToken> builder) {
int from = index;
int kuo = 0;
while (index < s.length()) {
index++;
char c = s.charAt(index);
try {
//Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
if (isLeftKuo(c)) {
kuo++;
continue;
}
if (isRightKuo(c)) {
if (kuo == 0) {
index++;
break;
} else {
kuo--;
continue;
}
}
}
builder.add(new CliTokenImpl(false, s.substring(from, index)));
return index;
}
private static boolean isBlank(char c) {
return c == ' ' || c == '\t';
}
private static boolean isLeftKuo(char c) {
return c == '(';
}
private static boolean isRightKuo(char c) {
return c == ')';
}
}

View File

@ -8,6 +8,7 @@
package com.lz.common.utils;
import com.lz.modules.app.utils.t.Tuple;
import org.apache.http.HttpStatus;
import java.util.HashMap;
@ -23,6 +24,8 @@ public class R extends HashMap<String, Object> {
private boolean isSuccess;
private Tuple tuple;
public R() {
put("code", 200);
put("msg", "success");
@ -45,6 +48,19 @@ public class R extends HashMap<String, Object> {
return r;
}
public R putObj(Tuple tuple) {
this.tuple = tuple;
return this;
}
public static R ok(int code) {
R r = new R();
r.put("code", code);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);

View File

@ -0,0 +1,60 @@
package com.lz.common.utils;
import com.lz.common.cli.CliToken;
import com.lz.common.cli.CliTokens;
import com.lz.modules.app.utils.t.Tuple;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TaskCommand {
public static final String add = "add";
public static final String update = "update";
public static final String list = "list";
public static final String task = "task";
public static final String record = "record";
public static List<String> commandCommands = new ArrayList<String>(Arrays.asList(new String[]{"add","update","list"}));
public static List<String> optTargets = new ArrayList<String>(Arrays.asList(new String[]{"task", "record"}));
public static Tuple parse(String command) {
String[] tokens = getTokens(command);
if (commandCommands.contains(tokens[0])) {
return new Tuple(488, "命令的第一个参数必需是 add or update or list");
}
if (optTargets.contains(tokens[1])) {
return new Tuple(488, "命令的第二个参数必需是 task or record");
}
if (task.equals(tokens[1])) { //表示对 task 增删改查
} else if (record.equals(tokens[1])) { //表示对 list 增删改查
}
return new Tuple();
}
public static String [] getTokens(String command) {
List<String> tokenList = new ArrayList<>();
List<CliToken> tokens = CliTokens.tokenize(command);
for (int i = 0; i < tokens.size(); i++) {
tokenList.add(tokens.get(i).value());
}
return tokenList.toArray(new String[tokenList.size()]);
}
@Test
public void test11() {
String ln = " abcdef b csssss dddddd -c \"b ccc ' bb a , bb x b\" a ";
List<CliToken> tokens = CliTokens.tokenize(ln);
for (int i = 0; i < tokens.size(); i++) {
System.out.println(tokens.get(i).value());
}
}
}

View File

@ -43,6 +43,9 @@ public class ThirdTaskController {
}
log.info("command:" + command);
List<List<String>> data = new ArrayList<>();
for (int i = 0; i < 5; i++) {
List<String> a = new ArrayList<>();
@ -52,6 +55,10 @@ public class ThirdTaskController {
data.add(a);
}
List<String> header = new ArrayList<>(Arrays.asList(new String[]{"用户名", "密码", "哈哈", "", "你是"}));
return R.ok().put("header", header).put("data", data);
}