技术标签: Android运行jython
/*
* Copyright (C) 2010 The Android Open Source Project
*
* 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.android.monkeyrunner;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.BreakIterator;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.python.core.ArgParser;
import org.python.core.ClassDictInit;
import org.python.core.Py;
import org.python.core.PyDictionary;
import org.python.core.PyFloat;
import org.python.core.PyInteger;
import org.python.core.PyList;
import org.python.core.PyNone;
import org.python.core.PyObject;
import org.python.core.PyReflectedField;
import org.python.core.PyReflectedFunction;
import org.python.core.PyString;
import org.python.core.PyStringMap;
import org.python.core.PyTuple;
import com.android.monkeyrunner.doc.MonkeyRunnerExported;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableMap.Builder;
/**
* Collection of useful utilities function for interacting with the Jython interpreter.
*/
public final class JythonUtils {
private static final Logger LOG = Logger.getLogger(JythonUtils.class.getCanonicalName());
private JythonUtils() { }
/**
* Mapping of PyObject classes to the java class we want to convert them to.
*/
private static final Map, Class>> PYOBJECT_TO_JAVA_OBJECT_MAP;
static {
Builder, Class>> builder = ImmutableMap.builder();
builder.put(PyString.class, String.class);
// What python calls float, most people call double
builder.put(PyFloat.class, Double.class);
builder.put(PyInteger.class, Integer.class);
PYOBJECT_TO_JAVA_OBJECT_MAP = builder.build();
}
/**
* Utility method to be called from Jython bindings to give proper handling of keyword and
* positional arguments.
*
* @param args the PyObject arguments from the binding
* @param kws the keyword arguments from the binding
* @return an ArgParser for this binding, or null on error
*/
public static ArgParser createArgParser(PyObject[] args, String[] kws) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
// Up 2 levels in the current stack to give us the calling function
StackTraceElement element = stackTrace[2];
String methodName = element.getMethodName();
String className = element.getClassName();
Class> clz;
try {
clz = Class.forName(className);
} catch (ClassNotFoundException e) {
LOG.log(Level.SEVERE, "Got exception: ", e);
return null;
}
Method m;
try {
m = clz.getMethod(methodName, PyObject[].class, String[].class);
} catch (SecurityException e) {
LOG.log(Level.SEVERE, "Got exception: ", e);
return null;
} catch (NoSuchMethodException e) {
LOG.log(Level.SEVERE, "Got exception: ", e);
return null;
}
MonkeyRunnerExported annotation = m.getAnnotation(MonkeyRunnerExported.class);
return new ArgParser(methodName, args, kws,
annotation.args());
}
/**
* Get a python floating point value from an ArgParser.
*
* @param ap the ArgParser to get the value from.
* @param position the position in the parser
* @return the double value
*/
public static double getFloat(ArgParser ap, int position) {
PyObject arg = ap.getPyObject(position);
if (Py.isInstance(arg, PyFloat.TYPE)) {
return ((PyFloat) arg).asDouble();
}
if (Py.isInstance(arg, PyInteger.TYPE)) {
return ((PyInteger) arg).asDouble();
}
throw Py.TypeError("Unable to parse argument: " + position);
}
/**
* Get a python floating point value from an ArgParser.
*
* @param ap the ArgParser to get the value from.
* @param position the position in the parser
* @param defaultValue the default value to return if the arg isn't specified.
* @return the double value
*/
public static double getFloat(ArgParser ap, int position, double defaultValue) {
PyObject arg = ap.getPyObject(position, new PyFloat(defaultValue));
if (Py.isInstance(arg, PyFloat.TYPE)) {
return ((PyFloat) arg).asDouble();
}
if (Py.isInstance(arg, PyInteger.TYPE)) {
return ((PyInteger) arg).asDouble();
}
throw Py.TypeError("Unable to parse argument: " + position);
}
/**
* Get a list of arguments from an ArgParser.
*
* @param ap the ArgParser
* @param position the position in the parser to get the argument from
* @return a list of those items
*/
@SuppressWarnings("unchecked")
public static List getList(ArgParser ap, int position) {
PyObject arg = ap.getPyObject(position, Py.None);
if (Py.isInstance(arg, PyNone.TYPE)) {
return Collections.emptyList();
}
List ret = Lists.newArrayList();
PyList array = (PyList) arg;
for (int x = 0; x < array.__len__(); x++) {
PyObject item = array.__getitem__(x);
Class> javaClass = PYOBJECT_TO_JAVA_OBJECT_MAP.get(item.getClass());
if (javaClass != null) {
ret.add(item.__tojava__(javaClass));
}
}
return ret;
}
/**
* Get a dictionary from an ArgParser. For ease of use, key types are always coerced to
* strings. If key type cannot be coeraced to string, an exception is raised.
*
* @param ap the ArgParser to work with
* @param position the position in the parser to get.
* @return a Map mapping the String key to the value
*/
public static Map getMap(ArgParser ap, int position) {
PyObject arg = ap.getPyObject(position, Py.None);
if (Py.isInstance(arg, PyNone.TYPE)) {
return Collections.emptyMap();
}
Map ret = Maps.newHashMap();
// cast is safe as getPyObjectbyType ensures it
PyDictionary dict = (PyDictionary) arg;
PyList items = dict.items();
for (int x = 0; x < items.__len__(); x++) {
// It's a list of tuples
PyTuple item = (PyTuple) items.__getitem__(x);
// We call str(key) on the key to get the string and then convert it to the java string.
String key = (String) item.__getitem__(0).__str__().__tojava__(String.class);
PyObject value = item.__getitem__(1);
// Look up the conversion type and convert the value
Class> javaClass = PYOBJECT_TO_JAVA_OBJECT_MAP.get(value.getClass());
if (javaClass != null) {
ret.put(key, value.__tojava__(javaClass));
}
}
return ret;
}
private static PyObject convertObject(Object o) {
if (o instanceof String) {
return new PyString((String) o);
} else if (o instanceof Double) {
return new PyFloat((Double) o);
} else if (o instanceof Integer) {
return new PyInteger((Integer) o);
} else if (o instanceof Float) {
float f = (Float) o;
return new PyFloat(f);
}
return Py.None;
}
/**
* Convert the given Java Map into a PyDictionary.
*
* @param map the map to convert
* @return the python dictionary
*/
public static PyDictionary convertMapToDict(Map map) {
Map resultMap = Maps.newHashMap();
for (Entry entry : map.entrySet()) {
resultMap.put(new PyString(entry.getKey()),
convertObject(entry.getValue()));
}
return new PyDictionary(resultMap);
}
/**
* This function should be called from classDictInit for any classes that are being exported
* to jython. This jython converts all the MonkeyRunnerExported annotations for the given class
* into the proper python form. It also removes any functions listed in the dictionary that
* aren't specifically annotated in the java class.
*
* NOTE: Make sure the calling class implements {@link ClassDictInit} to ensure that
* classDictInit gets called.
*
* @param clz the class to examine.
* @param dict the dictionary to update.
*/
public static void convertDocAnnotationsForClass(Class> clz, PyObject dict) {
Preconditions.checkNotNull(dict);
Preconditions.checkArgument(dict instanceof PyStringMap);
// See if the class has the annotation
if (clz.isAnnotationPresent(MonkeyRunnerExported.class)) {
MonkeyRunnerExported doc = clz.getAnnotation(MonkeyRunnerExported.class);
String fullDoc = buildClassDoc(doc, clz);
dict.__setitem__("__doc__", new PyString(fullDoc));
}
// Get all the keys from the dict and put them into a set. As we visit the annotated methods,
// we will remove them from this set. At the end, these are the "hidden" methods that
// should be removed from the dict
Collection functions = Sets.newHashSet();
for (PyObject item : dict.asIterable()) {
functions.add(item.toString());
}
// And remove anything that starts with __, as those are pretty important to retain
functions = Collections2.filter(functions, new Predicate() {
@Override
public boolean apply(String value) {
return !value.startsWith("__");
}
});
// Look at all the methods in the class and find the one's that have the
// @MonkeyRunnerExported annotation.
for (Method m : clz.getMethods()) {
if (m.isAnnotationPresent(MonkeyRunnerExported.class)) {
String methodName = m.getName();
PyObject pyFunc = dict.__finditem__(methodName);
if (pyFunc != null && pyFunc instanceof PyReflectedFunction) {
PyReflectedFunction realPyFunc = (PyReflectedFunction) pyFunc;
MonkeyRunnerExported doc = m.getAnnotation(MonkeyRunnerExported.class);
realPyFunc.__doc__ = new PyString(buildDoc(doc));
functions.remove(methodName);
}
}
}
// Also look at all the fields (both static and instance).
for (Field f : clz.getFields()) {
if (f.isAnnotationPresent(MonkeyRunnerExported.class)) {
String fieldName = f.getName();
PyObject pyField = dict.__finditem__(fieldName);
if (pyField != null && pyField instanceof PyReflectedField) {
PyReflectedField realPyfield = (PyReflectedField) pyField;
MonkeyRunnerExported doc = f.getAnnotation(MonkeyRunnerExported.class);
// TODO: figure out how to set field documentation. __doc__ is Read Only
// in this context.
// realPyfield.__setattr__("__doc__", new PyString(buildDoc(doc)));
functions.remove(fieldName);
}
}
}
// Now remove any elements left from the functions collection
for (String name : functions) {
dict.__delitem__(name);
}
}
private static final Predicate SHOULD_BE_DOCUMENTED = new Predicate() {
@Override
public boolean apply(AccessibleObject ao) {
return ao.isAnnotationPresent(MonkeyRunnerExported.class);
}
};
private static final Predicate IS_FIELD_STATIC = new Predicate() {
@Override
public boolean apply(Field f) {
return (f.getModifiers() & Modifier.STATIC) != 0;
}
};
/**
* build a jython doc-string for a class from the annotation and the fields
* contained within the class
*
* @param doc the annotation
* @param clz the class to be documented
* @return the doc-string
*/
private static String buildClassDoc(MonkeyRunnerExported doc, Class> clz) {
// Below the class doc, we need to document all the documented field this class contains
Collection annotatedFields = Collections2.filter(Arrays.asList(clz.getFields()), SHOULD_BE_DOCUMENTED);
Collection staticFields = Collections2.filter(annotatedFields, IS_FIELD_STATIC);
Collection nonStaticFields = Collections2.filter(annotatedFields, Predicates.not(IS_FIELD_STATIC));
StringBuilder sb = new StringBuilder();
for (String line : splitString(doc.doc(), 80)) {
sb.append(line).append("\n");
}
if (staticFields.size() > 0) {
sb.append("\nClass Fields: \n");
for (Field f : staticFields) {
sb.append(buildFieldDoc(f));
}
}
if (nonStaticFields.size() > 0) {
sb.append("\n\nFields: \n");
for (Field f : nonStaticFields) {
sb.append(buildFieldDoc(f));
}
}
return sb.toString();
}
/**
* Build a doc-string for the annotated field.
*
* @param f the field.
* @return the doc-string.
*/
private static String buildFieldDoc(Field f) {
MonkeyRunnerExported annotation = f.getAnnotation(MonkeyRunnerExported.class);
StringBuilder sb = new StringBuilder();
int indentOffset = 2 + 3 + f.getName().length();
String indent = makeIndent(indentOffset);
sb.append(" ").append(f.getName()).append(" - ");
boolean first = true;
for (String line : splitString(annotation.doc(), 80 - indentOffset)) {
if (first) {
first = false;
sb.append(line).append("\n");
} else {
sb.append(indent).append(line).append("\n");
}
}
return sb.toString();
}
/**
* Build a jython doc-string from the MonkeyRunnerExported annotation.
*
* @param doc the annotation to build from
* @return a jython doc-string
*/
private static String buildDoc(MonkeyRunnerExported doc) {
Collection docs = splitString(doc.doc(), 80);
StringBuilder sb = new StringBuilder();
for (String d : docs) {
sb.append(d).append("\n");
}
if (doc.args() != null && doc.args().length > 0) {
String[] args = doc.args();
String[] argDocs = doc.argDocs();
sb.append("\n Args:\n");
for (int x = 0; x < doc.args().length; x++) {
sb.append(" ").append(args[x]);
if (argDocs != null && argDocs.length > x) {
sb.append(" - ");
int indentOffset = args[x].length() + 3 + 4;
Collection lines = splitString(argDocs[x], 80 - indentOffset);
boolean first = true;
String indent = makeIndent(indentOffset);
for (String line : lines) {
if (first) {
first = false;
sb.append(line).append("\n");
} else {
sb.append(indent).append(line).append("\n");
}
}
}
}
}
return sb.toString();
}
private static String makeIndent(int indentOffset) {
if (indentOffset == 0) {
return "";
}
StringBuffer sb = new StringBuffer();
while (indentOffset > 0) {
sb.append(' ');
indentOffset--;
}
return sb.toString();
}
private static Collection splitString(String source, int offset) {
BreakIterator boundary = BreakIterator.getLineInstance();
boundary.setText(source);
List lines = Lists.newArrayList();
StringBuilder currentLine = new StringBuilder();
int start = boundary.first();
for (int end = boundary.next();
end != BreakIterator.DONE;
start = end, end = boundary.next()) {
String b = source.substring(start, end);
if (currentLine.length() + b.length() < offset) {
currentLine.append(b);
} else {
// emit the old line
lines.add(currentLine.toString());
currentLine = new StringBuilder(b);
}
}
lines.add(currentLine.toString());
return lines;
}
}
文章浏览阅读423次。应试者要想在面试答辩中获得成功,必须注意以下几个问题:(一)淡化面试的成败意识应试者对于面试的成败,首先在思想上应注意淡化,要有一种“不以物喜,不以己悲”的超然态度。如果在面试中有这样的心态,才会处变不惊。如果只想到成功,不想到失败,那么在面试中一遇到意外情况,就会惊慌失措,一败涂地。(二)保持自信应试者在面试前树立了自信,在面试中也要始终保持自信,只有保持了自信,才能够在面试中始终保持高度的注意力、缜密的思维力、敏锐的判断力、充沛的精力,夺取答辩的胜利。(三)保持愉悦的精神状态愉悦的精神状态,_竞选大队长时到台上演讲怎样不紧张端庄大方举止得体
文章浏览阅读2.1k次。select(查询)方法需要集合或者数组去装数据,而update(修改),delete(删除),insert(添加)方法是不需要设置返回类型的,它们都是默认返回一个int。/** * 查询水果 * @return */ @RequestMapping("/selFruit") public List<Fruit> selFruit(){ List<Fruit> list = fruitService...._springboot mapper查詢返回數字
文章浏览阅读4.2k次,点赞14次,收藏65次。项目实战:C/C++游戏:2048[C语言版]目录项目实战:C/C++游戏:2048[C语言版]1.编译环境2.项目运行效果3.思路简介:1.游戏规则2.核心算法4.主要源码:1.编译环境Win10专业版x64 VS2015这是2017年9或10月份写的 一个练手的,和上一篇Flappy Bird 是一起的, 留以后一个永久的回忆..._c++游戏
文章浏览阅读437次。特征选择(排序)对于数据科学家、机器学习从业者来说非常重要。好的特征选择能够提升模型的性能,更能帮助我们理解数据的特点、底层结构,这对进一步改善模型、算法都有着重要作用。特征选择主要有两个功能:减少特征数量、降维,使模型泛化能力更强,减少过拟合增强对特征和特征值之间的理解拿到数据集,一个特征选择方法,往往很难同时完成这两个目的。通常情况下,我们经常不管三七二十一,选择一种自己最熟悉或者最方便的特征..._python sklearn卡方检验选择特征
文章浏览阅读4.1k次。今天遇到一个很神奇的问题。 应用中有一个服务,服务中使用线程池 进行UDP的接收和发送。 但是,当锁屏后,数据无论如何都接收不到,当打开锁屏的时候,数据接收又恢复正常了。 并且,使用电源锁也没有任何效果。 PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); wl = pm.newWakeLoc_android接收udp组播熄屏收不到
文章浏览阅读450次。上图是一个Reactor线程模型,基于select(),epoll(),Reactor线程将I/O调用请求和I/O操作分离开,理论上一个Reactor线程能处理N个网络I/O操作,但是当并发量很大的时候,一个Reactor线程就会出现响应缓慢,连接超时等问题。============================================================那么一个Reacto_reactor线程组
文章浏览阅读2.5w次,点赞14次,收藏12次。利用PyCharm做项目,有时会有写文件(保存到项目中)的需求,但是可能是因为电脑比较慢,项目目录不会自动更新,需要自己手动刷新。可以自行设置“显示刷新图标”:view -->toolbar,需要刷新时,点一下就好了。_pycharm运行后,项目目录内的文件夹为啥不及时更新‘
文章浏览阅读2.5k次,点赞2次,收藏8次。python链表的建立。_python创建链表
文章浏览阅读5.7k次,点赞5次,收藏12次。Room是Jetpack组件库一员,属于ORM库,主要是对Sqlite做了一层抽象,从而简化开发者对数据库操作。Room支持编译时的语法检查,并且支持返..._jetpack room kapt
文章浏览阅读1.6k次。linux下 tar解压 gz解压 bz2等各种解压文件使用方法2010-03-23 15:15.tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) ——————————————— .gz 解压1:gunzip FileName.gz 解压2:gzip -_hornycraft解锁农场
文章浏览阅读571次。很好的入门解说,包括实现方式及意义第一次在知乎上发帖,有不准确的地方欢迎大家指正!!!,后续会持续更新知识图谱相关技术细节。本贴大概介绍一下知识图谱中相关的技术。知识图谱针对于知识图谱基础知识,领域应用和学术前沿趋势进行介绍。知识图谱介绍知识图谱(Knowledge Graph)以结构化的形式描述客观世界中概念、实体及其关系。是融合了认知计算、知识表示与推理、信息检索与抽取、自然语言处理、Web技术、机器学习与大数据挖掘等等方向的交叉学科。人工智能是以传统符号派与目前流行的深度神经._nerrdfs
文章浏览阅读4k次。Foreach标签foreach标签类似与volist标签,只是更加简单,没有太多额外的属性,例如:<foreach name="list" item="vo"> {$vo.id}:{$vo.name}</foreach>name表示数据源 item表示循环变量。可以输出索引,如下:<foreach name="list" item..._{foreach name="typelist" item="vo"}