{"action":"created","comment":{"url":"https://api.github.com/repos/apache/flink/pulls/comments/88614874","pull_request_review_id":9183291,"id":88614874,"diff_hunk":"@@ -0,0 +1,386 @@\n+/*\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\n+ * contributor license agreements.  See the NOTICE file distributed with\n+ * this work for additional information regarding copyright ownership.\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\n+ * (the \"License\"); you may not use this file except in compliance with\n+ * the License.  You may obtain a copy of the License at\n+ *\n+ *    http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package org.apache.flink.streaming.util.typeutils;\n+\n+import org.apache.flink.annotation.PublicEvolving;\n+import org.apache.flink.api.common.ExecutionConfig;\n+import org.apache.flink.api.common.operators.Keys;\n+import org.apache.flink.api.common.typeinfo.BasicTypeInfo;\n+import org.apache.flink.api.common.typeinfo.TypeInformation;\n+import org.apache.flink.api.common.typeutils.CompositeType;\n+import org.apache.flink.api.java.tuple.Tuple;\n+import org.apache.flink.api.java.typeutils.TupleTypeInfo;\n+import org.apache.flink.api.java.typeutils.TupleTypeInfoBase;\n+import org.apache.flink.api.java.typeutils.runtime.FieldSerializer;\n+import org.apache.flink.api.java.typeutils.runtime.TupleSerializerBase;\n+import scala.Product;\n+\n+import java.io.IOException;\n+import java.io.ObjectInputStream;\n+import java.io.ObjectOutputStream;\n+import java.io.Serializable;\n+import java.lang.reflect.Array;\n+import java.lang.reflect.Field;\n+import java.util.regex.Matcher;\n+import java.util.regex.Pattern;\n+\n+import static org.apache.flink.util.Preconditions.checkNotNull;\n+\n+\n+/**\n+ * These classes encapsulate the logic of accessing a field specified by the user as either an index\n+ * or a field expression string. TypeInformation can also be requested for the field.\n+ * The position index might specify a field of a Tuple, an array, or a simple type (only \"0th field\").\n+ *\n+ * Field expressions that specify nested fields (e.g. \"f1.a.foo\") result in nested field accessors.\n+ * These penetrate one layer, and then delegate the rest of the work to an \"innerAccesor\".\n+ * (see PojoFieldAccessor, RecursiveTupleFieldAccessor, ProductFieldAccessor)\n+ */\n+@PublicEvolving\n+public abstract class FieldAccessor<T, F> implements Serializable {\n+\n+\tprivate static final long serialVersionUID = 1L;\n+\n+\tprotected TypeInformation fieldType;\n+\n+\t/**\n+\t * Gets the TypeInformation for the type of the field.\n+\t * Note: For an array of a primitive type, it returns the corresponding basic type (Integer for int[]).\n+\t */\n+\t@SuppressWarnings(\"unchecked\")\n+\tpublic TypeInformation<F> getFieldType() {\n+\t\treturn fieldType;\n+\t}\n+\n+\n+\t/**\n+\t * Gets the value of the field (specified in the constructor) of the given record.\n+\t * @param record The record on which the field will be accessed\n+\t * @return The value of the field.\n+\t */\n+\tpublic abstract F get(T record);\n+\n+\t/**\n+\t * Sets the field (specified in the constructor) of the given record to the given value.\n+\t *\n+\t * Warning: This might modify the original object, or might return a new object instance.\n+\t * (This is necessary, because the record might be immutable.)\n+\t *\n+\t * @param record The record to modify\n+\t * @param fieldValue The new value of the field\n+\t * @return A record that has the given field value. (this might be a new instance or the original)\n+\t */\n+\tpublic abstract T set(T record, F fieldValue);\n+\n+\n+\t// --------------------------------------------------------------------------------------------------\n+\n+\n+\t/**\n+\t * This is when the entire record is considered as a single field. (eg. field 0 of a basic type, or a\n+\t * field of a POJO that is itself some composite type but is not further decomposed)\n+\t */\n+\tfinal static class SimpleFieldAccessor<T> extends FieldAccessor<T, T> {\n+\n+\t\tprivate static final long serialVersionUID = 1L;\n+\n+\t\tpublic SimpleFieldAccessor(TypeInformation<T> typeInfo) {\n+\t\t\tcheckNotNull(typeInfo, \"typeInfo must not be null.\");\n+\n+\t\t\tthis.fieldType = typeInfo;\n+\t\t}\n+\n+\t\t@Override\n+\t\tpublic T get(T record) {\n+\t\t\treturn record;\n+\t\t}\n+\n+\t\t@Override\n+\t\tpublic T set(T record, T fieldValue) {\n+\t\t\treturn fieldValue;\n+\t\t}\n+\t}\n+\n+\tfinal static class ArrayFieldAccessor<T, F> extends FieldAccessor<T, F> {\n+\n+\t\tprivate static final long serialVersionUID = 1L;\n+\n+\t\tprivate final int pos;\n+\n+\t\tpublic ArrayFieldAccessor(int pos, TypeInformation typeInfo) {\n+\t\t\tif(pos < 0) {\n+\t\t\t\tthrow new CompositeType.InvalidFieldReferenceException(\"The \" + ((Integer) pos).toString() + \". field selected on\" +\n+\t\t\t\t\t\" an array, which is an invalid index.\");\n+\t\t\t}\n+\t\t\tcheckNotNull(typeInfo, \"typeInfo must not be null.\");\n+\n+\t\t\tthis.pos = pos;\n+\t\t\tthis.fieldType = BasicTypeInfo.getInfoFor(typeInfo.getTypeClass().getComponentType());\n+\t\t}\n+\n+\t\t@SuppressWarnings(\"unchecked\")\n+\t\t@Override\n+\t\tpublic F get(T record) {\n+\t\t\treturn (F) Array.get(record, pos);\n+\t\t}\n+\n+\t\t@Override\n+\t\tpublic T set(T record, F fieldValue) {\n+\t\t\tArray.set(record, pos, fieldValue);\n+\t\t\treturn record;\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * There are two versions of TupleFieldAccessor, differing in whether there is an other\n+\t * FieldAccessor nested inside. The no inner accessor version is probably a little faster.\n+\t */\n+\tstatic final class SimpleTupleFieldAccessor<T, F> extends FieldAccessor<T, F> {\n+\n+\t\tprivate static final long serialVersionUID = 1L;\n+\n+\t\tprivate final int pos;\n+\n+\t\tSimpleTupleFieldAccessor(int pos, TypeInformation<T> typeInfo) {\n+\t\t\tcheckNotNull(typeInfo, \"typeInfo must not be null.\");\n+\t\t\tint arity = ((TupleTypeInfo)typeInfo).getArity();\n+\t\t\tif(pos < 0 || pos >= arity) {\n+\t\t\t\tthrow new CompositeType.InvalidFieldReferenceException(\n+\t\t\t\t\t\"Tried to select \" + ((Integer) pos).toString() + \". field on \\\"\" +\n+\t\t\t\t\ttypeInfo.toString() + \"\\\", which is an invalid index.\");\n+\t\t\t}\n+\n+\t\t\tthis.pos = pos;\n+\t\t\tthis.fieldType = ((TupleTypeInfo)typeInfo).getTypeAt(pos);\n+\t\t}\n+\n+\t\t@SuppressWarnings(\"unchecked\")\n+\t\t@Override\n+\t\tpublic F get(T record) {\n+\t\t\tfinal Tuple tuple = (Tuple) record;\n+\t\t\treturn (F) tuple.getField(pos);\n+\t\t}\n+\n+\t\t@Override\n+\t\tpublic T set(T record, F fieldValue) {\n+\t\t\tfinal Tuple tuple = (Tuple) record;\n+\t\t\ttuple.setField(fieldValue, pos);\n+\t\t\treturn record;\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * @param <T> The Tuple type\n+\t * @param <R> The field type at the first level\n+\t * @param <F> The field type at the innermost level\n+\t */\n+\tstatic final class RecursiveTupleFieldAccessor<T, R, F> extends FieldAccessor<T, F> {","path":"flink-streaming-java/src/main/java/org/apache/flink/streaming/util/typeutils/FieldAccessor.java","position":192,"original_position":192,"commit_id":"95de75097c1eaa89ddab52d4d93862f992b4924f","original_commit_id":"95de75097c1eaa89ddab52d4d93862f992b4924f","user":{"login":"mbalassi","id":5990983,"avatar_url":"https://avatars.githubusercontent.com/u/5990983?v=3","gravatar_id":"","url":"https://api.github.com/users/mbalassi","html_url":"https://github.com/mbalassi","followers_url":"https://api.github.com/users/mbalassi/followers","following_url":"https://api.github.com/users/mbalassi/following{/other_user}","gists_url":"https://api.github.com/users/mbalassi/gists{/gist_id}","starred_url":"https://api.github.com/users/mbalassi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbalassi/subscriptions","organizations_url":"https://api.github.com/users/mbalassi/orgs","repos_url":"https://api.github.com/users/mbalassi/repos","events_url":"https://api.github.com/users/mbalassi/events{/privacy}","received_events_url":"https://api.github.com/users/mbalassi/received_events","type":"User","site_admin":false},"body":"Yep.","created_at":"2016-11-18T08:20:02Z","updated_at":"2016-11-18T08:20:02Z","html_url":"https://github.com/apache/flink/pull/2094#discussion_r88614874","pull_request_url":"https://api.github.com/repos/apache/flink/pulls/2094","_links":{"self":{"href":"https://api.github.com/repos/apache/flink/pulls/comments/88614874"},"html":{"href":"https://github.com/apache/flink/pull/2094#discussion_r88614874"},"pull_request":{"href":"https://api.github.com/repos/apache/flink/pulls/2094"}}},"pull_request":{"url":"https://api.github.com/repos/apache/flink/pulls/2094","id":73503387,"html_url":"https://github.com/apache/flink/pull/2094","diff_url":"https://github.com/apache/flink/pull/2094.diff","patch_url":"https://github.com/apache/flink/pull/2094.patch","issue_url":"https://api.github.com/repos/apache/flink/issues/2094","number":2094,"state":"open","locked":false,"title":"[FLINK-3702] Make FieldAccessors support nested field expressions.","user":{"login":"ggevay","id":11377925,"avatar_url":"https://avatars.githubusercontent.com/u/11377925?v=3","gravatar_id":"","url":"https://api.github.com/users/ggevay","html_url":"https://github.com/ggevay","followers_url":"https://api.github.com/users/ggevay/followers","following_url":"https://api.github.com/users/ggevay/following{/other_user}","gists_url":"https://api.github.com/users/ggevay/gists{/gist_id}","starred_url":"https://api.github.com/users/ggevay/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ggevay/subscriptions","organizations_url":"https://api.github.com/users/ggevay/orgs","repos_url":"https://api.github.com/users/ggevay/repos","events_url":"https://api.github.com/users/ggevay/events{/privacy}","received_events_url":"https://api.github.com/users/ggevay/received_events","type":"User","site_admin":false},"body":"I finally had some time to complete this, sorry it took so long.\n\nI have added `getFieldAccessor` to `TypeInformation`, which creates a `FieldAccessor` from a position or a (possibly nested) field expression. It uses recursion in the nested case, and also supports the heterogeneous case, e.g. pojo inside tuple inside pojo.\n\nAdditionally, I have noticed that the code to serialize/deserialize a `java.lang.reflect.Field` is duplicated at several places (`readObject`/`writeObject` of `PojoSerializer`, `PojoComparator`, `PojoField`). I also needed it in `PojoFieldAccessor`, so instead of adding more duplication, I factored it out into a new class (`FieldSerializer`).\n","created_at":"2016-06-12T18:35:15Z","updated_at":"2016-11-18T08:20:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ffca00952d70853871e52cd1a3dabd4d5a318d2c","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/apache/flink/pulls/2094/commits","review_comments_url":"https://api.github.com/repos/apache/flink/pulls/2094/comments","review_comment_url":"https://api.github.com/repos/apache/flink/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/flink/issues/2094/comments","statuses_url":"https://api.github.com/repos/apache/flink/statuses/95de75097c1eaa89ddab52d4d93862f992b4924f","head":{"label":"ggevay:FieldAccessorRefactor","ref":"FieldAccessorRefactor","sha":"95de75097c1eaa89ddab52d4d93862f992b4924f","user":{"login":"ggevay","id":11377925,"avatar_url":"https://avatars.githubusercontent.com/u/11377925?v=3","gravatar_id":"","url":"https://api.github.com/users/ggevay","html_url":"https://github.com/ggevay","followers_url":"https://api.github.com/users/ggevay/followers","following_url":"https://api.github.com/users/ggevay/following{/other_user}","gists_url":"https://api.github.com/users/ggevay/gists{/gist_id}","starred_url":"https://api.github.com/users/ggevay/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ggevay/subscriptions","organizations_url":"https://api.github.com/users/ggevay/orgs","repos_url":"https://api.github.com/users/ggevay/repos","events_url":"https://api.github.com/users/ggevay/events{/privacy}","received_events_url":"https://api.github.com/users/ggevay/received_events","type":"User","site_admin":false},"repo":{"id":31857829,"name":"flink","full_name":"ggevay/flink","owner":{"login":"ggevay","id":11377925,"avatar_url":"https://avatars.githubusercontent.com/u/11377925?v=3","gravatar_id":"","url":"https://api.github.com/users/ggevay","html_url":"https://github.com/ggevay","followers_url":"https://api.github.com/users/ggevay/followers","following_url":"https://api.github.com/users/ggevay/following{/other_user}","gists_url":"https://api.github.com/users/ggevay/gists{/gist_id}","starred_url":"https://api.github.com/users/ggevay/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ggevay/subscriptions","organizations_url":"https://api.github.com/users/ggevay/orgs","repos_url":"https://api.github.com/users/ggevay/repos","events_url":"https://api.github.com/users/ggevay/events{/privacy}","received_events_url":"https://api.github.com/users/ggevay/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ggevay/flink","description":"Mirror of Apache Flink","fork":true,"url":"https://api.github.com/repos/ggevay/flink","forks_url":"https://api.github.com/repos/ggevay/flink/forks","keys_url":"https://api.github.com/repos/ggevay/flink/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ggevay/flink/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ggevay/flink/teams","hooks_url":"https://api.github.com/repos/ggevay/flink/hooks","issue_events_url":"https://api.github.com/repos/ggevay/flink/issues/events{/number}","events_url":"https://api.github.com/repos/ggevay/flink/events","assignees_url":"https://api.github.com/repos/ggevay/flink/assignees{/user}","branches_url":"https://api.github.com/repos/ggevay/flink/branches{/branch}","tags_url":"https://api.github.com/repos/ggevay/flink/tags","blobs_url":"https://api.github.com/repos/ggevay/flink/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ggevay/flink/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ggevay/flink/git/refs{/sha}","trees_url":"https://api.github.com/repos/ggevay/flink/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ggevay/flink/statuses/{sha}","languages_url":"https://api.github.com/repos/ggevay/flink/languages","stargazers_url":"https://api.github.com/repos/ggevay/flink/stargazers","contributors_url":"https://api.github.com/repos/ggevay/flink/contributors","subscribers_url":"https://api.github.com/repos/ggevay/flink/subscribers","subscription_url":"https://api.github.com/repos/ggevay/flink/subscription","commits_url":"https://api.github.com/repos/ggevay/flink/commits{/sha}","git_commits_url":"https://api.github.com/repos/ggevay/flink/git/commits{/sha}","comments_url":"https://api.github.com/repos/ggevay/flink/comments{/number}","issue_comment_url":"https://api.github.com/repos/ggevay/flink/issues/comments{/number}","contents_url":"https://api.github.com/repos/ggevay/flink/contents/{+path}","compare_url":"https://api.github.com/repos/ggevay/flink/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ggevay/flink/merges","archive_url":"https://api.github.com/repos/ggevay/flink/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ggevay/flink/downloads","issues_url":"https://api.github.com/repos/ggevay/flink/issues{/number}","pulls_url":"https://api.github.com/repos/ggevay/flink/pulls{/number}","milestones_url":"https://api.github.com/repos/ggevay/flink/milestones{/number}","notifications_url":"https://api.github.com/repos/ggevay/flink/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ggevay/flink/labels{/name}","releases_url":"https://api.github.com/repos/ggevay/flink/releases{/id}","deployments_url":"https://api.github.com/repos/ggevay/flink/deployments","created_at":"2015-03-08T17:06:03Z","updated_at":"2016-01-18T13:00:12Z","pushed_at":"2016-11-06T12:13:22Z","git_url":"git://github.com/ggevay/flink.git","ssh_url":"git@github.com:ggevay/flink.git","clone_url":"https://github.com/ggevay/flink.git","svn_url":"https://github.com/ggevay/flink","homepage":null,"size":98253,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"3a4fc537dcff4961d4b0c7d11347d246d5b4d293","user":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":20587599,"name":"flink","full_name":"apache/flink","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/flink","description":"Mirror of Apache Flink","fork":false,"url":"https://api.github.com/repos/apache/flink","forks_url":"https://api.github.com/repos/apache/flink/forks","keys_url":"https://api.github.com/repos/apache/flink/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/flink/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/flink/teams","hooks_url":"https://api.github.com/repos/apache/flink/hooks","issue_events_url":"https://api.github.com/repos/apache/flink/issues/events{/number}","events_url":"https://api.github.com/repos/apache/flink/events","assignees_url":"https://api.github.com/repos/apache/flink/assignees{/user}","branches_url":"https://api.github.com/repos/apache/flink/branches{/branch}","tags_url":"https://api.github.com/repos/apache/flink/tags","blobs_url":"https://api.github.com/repos/apache/flink/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/flink/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/flink/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/flink/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/flink/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/flink/languages","stargazers_url":"https://api.github.com/repos/apache/flink/stargazers","contributors_url":"https://api.github.com/repos/apache/flink/contributors","subscribers_url":"https://api.github.com/repos/apache/flink/subscribers","subscription_url":"https://api.github.com/repos/apache/flink/subscription","commits_url":"https://api.github.com/repos/apache/flink/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/flink/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/flink/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/flink/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/flink/contents/{+path}","compare_url":"https://api.github.com/repos/apache/flink/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/flink/merges","archive_url":"https://api.github.com/repos/apache/flink/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/flink/downloads","issues_url":"https://api.github.com/repos/apache/flink/issues{/number}","pulls_url":"https://api.github.com/repos/apache/flink/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/flink/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/flink/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/flink/labels{/name}","releases_url":"https://api.github.com/repos/apache/flink/releases{/id}","deployments_url":"https://api.github.com/repos/apache/flink/deployments","created_at":"2014-06-07T07:00:10Z","updated_at":"2016-11-18T07:43:40Z","pushed_at":"2016-11-18T01:38:17Z","git_url":"git://github.com/apache/flink.git","ssh_url":"git@github.com:apache/flink.git","clone_url":"https://github.com/apache/flink.git","svn_url":"https://github.com/apache/flink","homepage":null,"size":142575,"stargazers_count":1759,"watchers_count":1759,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1189,"mirror_url":"git://git.apache.org/flink.git","open_issues_count":178,"forks":1189,"open_issues":178,"watchers":1759,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/flink/pulls/2094"},"html":{"href":"https://github.com/apache/flink/pull/2094"},"issue":{"href":"https://api.github.com/repos/apache/flink/issues/2094"},"comments":{"href":"https://api.github.com/repos/apache/flink/issues/2094/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/flink/pulls/2094/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/flink/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/flink/pulls/2094/commits"},"statuses":{"href":"https://api.github.com/repos/apache/flink/statuses/95de75097c1eaa89ddab52d4d93862f992b4924f"}}}}
{"actor":{"display_login":"mbalassi"}}