创建“除非”语句作为用户定义脚本的绑定

时间:2018-10-07 16:04:54

标签: groovy scripting groovyshell

我有一项任务,需要为用户脚本实现一个处理器,该脚本的一部分出现在脚本unless中,并且其行为与if statement相反。有没有办法创建一个像这样的binding。 我是Groovy的新手,所以也许我的解释不太清楚,但是我的代码可以告诉我更多关于我的问题的信息。除非用if statement替换,否则效果很好,但是我需要制作unless的想法。

static List<String> filterSitesByUserScript(String userScript, List<String> sites) {

  //properties
  List<String> rememberedSites = new ArrayList<String>()

  //binding
  def binding = new Binding()
  binding['allSites'] = sites
  binding['rememberedSites'] = rememberedSites
  binding['download'] = {String site ->
      new URL(site).getText()
  }
  //binding['unless'] = {statement -> statement == !statement}
  binding['siteTalksAboutGroovy'] = { content -> content.contains("groovy") || content.contains("Groovy") }
  binding['remember'] = { String site -> rememberedSites.add(site)}

  //groovy shell
  GroovyShell shell = new GroovyShell(binding)
  shell.evaluate(userScript)

  return rememberedSites
}

//A test user script input.
String userInput = '''
   for(site in allSites) {
       def content = download site
       unless (siteTalksAboutGroovy(content)) {
           remember site
       }
   }
   return rememberedSites
'''

//Calling the filtering method on a list of sites.
sites = ["http://groovy.cz", "http://gpars.org", "http://groovy-lang.org/", "http://infoq.com", "http://oracle.com", "http://ibm.com"]
def result = filterSitesByUserScript(userInput, sites)
result.each {
    println 'No groovy mention at ' + it
}
assert result.size() > 0 && result.size() < sites.size
println 'ok'

1 个答案:

答案 0 :(得分:2)

如果要执行以下代码:

 String[] javascript =
            {
                    "<html>  \n </html>",
                    "<body> \n </body",
                    "<head>",
                    "</head>",
                    "<script>",
                    "</script>",
                    "<h>",
                    "</h>",
                    "<h1>",
                    "</h2>",
                    "<h3>",
                    "</h3>",
                    "<h4>",
                    "</h4>",
                    "img",
                    "<button>",
                    "</button>",
                    "function",
                    "document.write()",
                    "document.getElementById()",
                    ".innerHTML",
                    "alert",
            "<p>",
            "</p>"};
public class SpaceTokenizer implements MultiAutoCompleteTextView.Tokenizer {

        public int findTokenStart(CharSequence text, int cursor) {
            int i = cursor;


            if (i>0 && text.charAt(i-1)!= '\n') {
                while (i > 0 && text.charAt(i - 1) != '\n') {
                    i--;
                }
                while (i < cursor && text.charAt(i) == '\n') {
                    i++;
                }

                return i;
            }
            else if (i>0 && text.charAt(i-1)!= ' ') {
                while (i > 0 && text.charAt(i - 1) != ' ') {
                    i--;
                }
                while (i < cursor && text.charAt(i) == ' ') {
                    i++;
                }

                return i;
            }
            else if (i>0 && text.charAt(i-1)!= '<') {
                while (i > 0 && text.charAt(i - 1) != '<') {
                    i--;
                }
                while (i < cursor && text.charAt(i) == '<') {
                    i++;
                }

                return i;
            }
           return i;
        }

        public int findTokenEnd(CharSequence text, int cursor) {
            int i = cursor;
            int len = text.length();

            if (text.charAt(i) == ' ') {

                while (i < len) {
                    if (text.charAt(i) == ' ') {
                        return i;
                    } else {
                        i++;
                    }
                }
                return len;
            }
            else if (text.charAt(i)== '>'){

                while (i < len) {
                    if (text.charAt(i) == ' ') {
                        return i;
                    } else {
                        i++;
                    }
                }

            }
            return len;
        }

        public CharSequence terminateToken(CharSequence text) {
            int i = text.length();

            while (i > 0 && text.charAt(i - 1) == '>') {
                i--;
            }

            if (i > 0 && text.charAt(i - 1) == '>') {
                return text;
            } else {
                if (text instanceof Spanned) {
                    SpannableString sp = new SpannableString(text);
                    TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
                            Object.class, sp, 0);
                    return sp;
                } else {
                    return text ;
                }
            }
        }
    }

您可以创建一个绑定unless (siteTalksAboutGroovy(content)) { remember site } 来存储带有两个参数的闭包:

unless

仅当第一个参数binding['unless'] = { test, block -> if (!test) block() } 为false时,此闭包才执行block()。如果您的示例使用test闭包运行代码,则会产生以下输出:

unless