From be4dbd13e8fae2bc9454e8889b1687e8d1270eb9 Mon Sep 17 00:00:00 2001 From: DuyHai DOAN Date: Sun, 3 Apr 2016 20:02:09 +0200 Subject: [PATCH] [ZEPPELIN-697] Replace dynamic form with angular object from registry if exists --- .../apache/zeppelin/notebook/Paragraph.java | 28 ++++++++++ .../display/AngularObjectBuilder.java | 26 ++++++++++ .../zeppelin/notebook/ParagraphTest.java | 52 ++++++++++++++++++- 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 zeppelin-zengine/src/test/java/org/apache/zeppelin/display/AngularObjectBuilder.java diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java index bb4d69b717f..5778d0da4ab 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java @@ -17,6 +17,7 @@ package org.apache.zeppelin.notebook; +import org.apache.zeppelin.display.AngularObject; import org.apache.zeppelin.display.AngularObjectRegistry; import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.display.GUI; @@ -232,6 +233,12 @@ protected Object jobRun() throws Throwable { String scriptBody = getScriptBody(); Map inputs = Input.extractSimpleQueryParam(scriptBody); // inputs will be built // from script body + + final AngularObjectRegistry angularRegistry = repl.getInterpreterGroup() + .getAngularObjectRegistry(); + + scriptBody = extractVariablesFromAngularRegistry(scriptBody, inputs, angularRegistry); + settings.setForms(inputs); script = Input.getSimpleQuery(settings.getParams(), scriptBody); } @@ -390,4 +397,25 @@ public Object clone() throws CloneNotSupportedException { Paragraph paraClone = (Paragraph) this.clone(); return paraClone; } + + String extractVariablesFromAngularRegistry(String scriptBody, Map inputs, + AngularObjectRegistry angularRegistry) { + + final String noteId = this.getNote().getId(); + final String paragraphId = this.getId(); + + final Set keys = new HashSet<>(inputs.keySet()); + + for (String varName : keys) { + final AngularObject paragraphScoped = angularRegistry.get(varName, noteId, paragraphId); + final AngularObject noteScoped = angularRegistry.get(varName, noteId, null); + final AngularObject angularObject = paragraphScoped != null ? paragraphScoped : noteScoped; + if (angularObject != null) { + inputs.remove(varName); + final String pattern = "[$][{]\\s*" + varName + "\\s*(?:=[^}]+)?[}]"; + scriptBody = scriptBody.replaceAll(pattern, angularObject.get().toString()); + } + } + return scriptBody; + } } diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/display/AngularObjectBuilder.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/display/AngularObjectBuilder.java new file mode 100644 index 00000000000..c2018588cf3 --- /dev/null +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/display/AngularObjectBuilder.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.zeppelin.display; + +public class AngularObjectBuilder { + + public static AngularObject build(String varName, T value, String noteId, + String paragraphId) { + return new AngularObject<>(varName, value, noteId, paragraphId, null); + } +} \ No newline at end of file diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/ParagraphTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/ParagraphTest.java index 87805cef133..a594873806d 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/ParagraphTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/ParagraphTest.java @@ -17,9 +17,20 @@ package org.apache.zeppelin.notebook; -import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.apache.zeppelin.display.AngularObject; +import org.apache.zeppelin.display.AngularObjectBuilder; +import org.apache.zeppelin.display.AngularObjectRegistry; +import org.apache.zeppelin.display.Input; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; public class ParagraphTest { @Test @@ -35,4 +46,43 @@ public void scriptBodyWithoutReplName() { String text = "12345678"; assertEquals(text, Paragraph.getScriptBody(text)); } + + @Test + public void should_extract_variable_from_angular_object_registry() throws Exception { + //Given + final String noteId = "noteId"; + + final AngularObjectRegistry registry = mock(AngularObjectRegistry.class); + final Note note = mock(Note.class); + final Map inputs = new HashMap<>(); + inputs.put("name", null); + inputs.put("age", null); + inputs.put("job", null); + + final String scriptBody = "My name is ${name} and I am ${age=20} years old. " + + "My occupation is ${ job = engineer | developer | artists}"; + + final Paragraph paragraph = new Paragraph(note, null, null); + final String paragraphId = paragraph.getId(); + + final AngularObject nameAO = AngularObjectBuilder.build("name", "DuyHai DOAN", noteId, + paragraphId); + + final AngularObject ageAO = AngularObjectBuilder.build("age", 34, noteId, null); + + when(note.getId()).thenReturn(noteId); + when(registry.get("name", noteId, paragraphId)).thenReturn(nameAO); + when(registry.get("age", noteId, null)).thenReturn(ageAO); + + final String expected = "My name is DuyHai DOAN and I am 34 years old. " + + "My occupation is ${ job = engineer | developer | artists}"; + //When + final String actual = paragraph.extractVariablesFromAngularRegistry(scriptBody, inputs, + registry); + + //Then + verify(registry).get("name", noteId, paragraphId); + verify(registry).get("age", noteId, null); + assertEquals(actual, expected); + } }