org.apache.zeppelin.notebook.Paragraph Maven / Gradle / Ivy
/*
* 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.notebook;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.zeppelin.display.AngularObjectRegistry;
import org.apache.zeppelin.display.GUI;
import org.apache.zeppelin.display.Input;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.Interpreter.FormType;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterContextRunner;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterSetting;
import org.apache.zeppelin.scheduler.Job;
import org.apache.zeppelin.scheduler.JobListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Paragraph is a representation of an execution unit.
*
* @author Leemoonsoo
*/
public class Paragraph extends Job implements Serializable {
private static final transient long serialVersionUID = -6328572073497992016L;
private transient NoteInterpreterLoader replLoader;
private transient Note note;
String title;
String text;
private Map config; // paragraph configs like isOpen, colWidth, etc
public final GUI settings; // form and parameter settings
public Paragraph(Note note, JobListener listener, NoteInterpreterLoader replLoader) {
super(generateId(), listener);
this.note = note;
this.replLoader = replLoader;
title = null;
text = null;
settings = new GUI();
config = new HashMap();
}
private static String generateId() {
return "paragraph_" + System.currentTimeMillis() + "_"
+ new Random(System.currentTimeMillis()).nextInt();
}
public String getText() {
return text;
}
public void setText(String newText) {
this.text = newText;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setNote(Note note) {
this.note = note;
}
public Note getNote() {
return note;
}
public String getRequiredReplName() {
return getRequiredReplName(text);
}
public static String getRequiredReplName(String text) {
if (text == null) {
return null;
}
// get script head
int scriptHeadIndex = 0;
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (ch == ' ' || ch == '\n') {
scriptHeadIndex = i;
break;
}
}
if (scriptHeadIndex == 0) {
return null;
}
String head = text.substring(0, scriptHeadIndex);
if (head.startsWith("%")) {
return head.substring(1);
} else {
return null;
}
}
private String getScriptBody() {
return getScriptBody(text);
}
public static String getScriptBody(String text) {
if (text == null) {
return null;
}
String magic = getRequiredReplName(text);
if (magic == null) {
return text;
}
if (magic.length() + 2 >= text.length()) {
return "";
}
return text.substring(magic.length() + 2);
}
public NoteInterpreterLoader getNoteReplLoader() {
return replLoader;
}
public Interpreter getRepl(String name) {
return replLoader.get(name);
}
public List completion(String buffer, int cursor) {
String replName = getRequiredReplName(buffer);
if (replName != null) {
cursor -= replName.length() + 1;
}
String body = getScriptBody(buffer);
Interpreter repl = getRepl(replName);
if (repl == null) {
return null;
}
return repl.completion(body, cursor);
}
public void setNoteReplLoader(NoteInterpreterLoader repls) {
this.replLoader = repls;
}
public InterpreterResult getResult() {
return (InterpreterResult) getReturn();
}
@Override
public int progress() {
String replName = getRequiredReplName();
Interpreter repl = getRepl(replName);
if (repl != null) {
return repl.getProgress(getInterpreterContext());
} else {
return 0;
}
}
@Override
public Map info() {
return null;
}
@Override
protected Object jobRun() throws Throwable {
String replName = getRequiredReplName();
Interpreter repl = getRepl(replName);
logger().info("run paragraph {} using {} " + repl, getId(), replName);
if (repl == null) {
logger().error("Can not find interpreter name " + repl);
throw new RuntimeException("Can not find interpreter for " + getRequiredReplName());
}
String script = getScriptBody();
// inject form
if (repl.getFormType() == FormType.NATIVE) {
settings.clear();
} else if (repl.getFormType() == FormType.SIMPLE) {
String scriptBody = getScriptBody();
Map inputs = Input.extractSimpleQueryParam(scriptBody); // inputs will be built
// from script body
settings.setForms(inputs);
script = Input.getSimpleQuery(settings.getParams(), scriptBody);
}
logger().info("RUN : " + script);
InterpreterResult ret = repl.interpret(script, getInterpreterContext());
return ret;
}
@Override
protected boolean jobAbort() {
Interpreter repl = getRepl(getRequiredReplName());
repl.cancel(getInterpreterContext());
return true;
}
private InterpreterContext getInterpreterContext() {
AngularObjectRegistry registry = null;
if (!getNoteReplLoader().getInterpreterSettings().isEmpty()) {
InterpreterSetting intpGroup = getNoteReplLoader().getInterpreterSettings().get(0);
registry = intpGroup.getInterpreterGroup().getAngularObjectRegistry();
}
List runners = new LinkedList();
for (Paragraph p : note.getParagraphs()) {
runners.add(new ParagraphRunner(note, note.id(), p.getId()));
}
InterpreterContext interpreterContext = new InterpreterContext(getId(),
this.getTitle(),
this.getText(),
this.getConfig(),
this.settings,
registry,
runners);
return interpreterContext;
}
static class ParagraphRunner extends InterpreterContextRunner {
private Note note;
public ParagraphRunner(Note note, String noteId, String paragraphId) {
super(noteId, paragraphId);
this.note = note;
}
@Override
public void run() {
note.run(getParagraphId());
}
}
private Logger logger() {
Logger logger = LoggerFactory.getLogger(Paragraph.class);
return logger;
}
public Map getConfig() {
return config;
}
public void setConfig(Map config) {
this.config = config;
}
public void setReturn(InterpreterResult value, Throwable t) {
setResult(value);
setException(t);
}
}