Java tutorial
/* * 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 se.kth.hopsworks.zeppelin.notebook.repo; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.commons.vfs2.FileContent; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemManager; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.NameScope; import org.apache.commons.vfs2.Selectors; import org.apache.commons.vfs2.VFS; import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; import org.apache.zeppelin.notebook.Note; import org.apache.zeppelin.notebook.NoteInfo; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.notebook.repo.NotebookRepo; import org.apache.zeppelin.scheduler.Job.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import se.kth.bbc.project.Project; /** * */ public class FSNotebookRepo implements NotebookRepo { Logger logger = LoggerFactory.getLogger(FSNotebookRepo.class); private FileSystemManager fsManager; private URI filesystemRoot; private Project project; private ZeppelinConfiguration conf; public FSNotebookRepo(ZeppelinConfiguration conf, Project project) throws IOException { this.conf = conf; this.project = project; try { filesystemRoot = new URI(conf.getNotebookDir()); } catch (URISyntaxException e1) { throw new IOException(e1); } if (filesystemRoot.getScheme() == null) { // it is local path try { this.filesystemRoot = new URI( new File(conf.getRelativeDir(filesystemRoot.getPath())).getAbsolutePath()); } catch (URISyntaxException e) { throw new IOException(e); } } else { this.filesystemRoot = filesystemRoot; } fsManager = VFS.getManager(); } private String getPath(String path) { if (path == null || path.trim().length() == 0) { return filesystemRoot.toString(); } if (path.startsWith("/")) { return filesystemRoot.toString() + path; } else { return filesystemRoot.toString() + "/" + path; } } private boolean isDirectory(FileObject fo) throws IOException { if (fo == null) { return false; } if (fo.getType() == FileType.FOLDER) { return true; } else { return false; } } private LinkedList<FileObject> getNotes(FileObject root, FileObject proj) throws IOException { FileObject[] rootchildren = root.getChildren(); FileObject[] projChildren; LinkedList<FileObject> children = new LinkedList<>(); if (isDirectory(proj)) { projChildren = proj.getChildren(); if (projChildren != null) { children = new LinkedList<>(Arrays.asList(projChildren)); } } // add notes in the root dir that are not project specific ex. tutorials for (FileObject f : rootchildren) { if (isDirectory(f)) { FileObject noteJson = f.resolveFile("note.json", NameScope.CHILD); if (noteJson.exists() && !listContainsNote(children, f)) { children.add(f); } } } return children; } private boolean listContainsNote(List<FileObject> list, FileObject note) { for (FileObject fileObj : list) { if (fileObj.getName().getBaseName().equals(note.getName().getBaseName())) { return true; } } return false; } @Override public List<NoteInfo> list() throws IOException { FileObject rootDir = getRootDir(); FileObject projectDir = null; if (this.project != null) { projectDir = rootDir.resolveFile(this.project.getName(), NameScope.CHILD); } LinkedList<FileObject> children = getNotes(rootDir, projectDir); List<NoteInfo> infos = new LinkedList<>(); for (FileObject f : children) { String fileName = f.getName().getBaseName(); if (f.isHidden() || fileName.startsWith(".") || fileName.startsWith("#") || fileName.startsWith("~")) { // skip hidden, temporary files continue; } if (!isDirectory(f)) { // currently single note is saved like, [NOTE_ID]/note.json. // so it must be a directory continue; } NoteInfo info = null; try { info = getNoteInfo(f); if (info != null) { infos.add(info); } } catch (IOException e) { logger.error("Can't read note " + f.getName().toString(), e); } } return infos; } private Note getNote(FileObject noteDir) throws IOException { if (!isDirectory(noteDir)) { throw new IOException(noteDir.getName().toString() + " is not a directory"); } FileObject noteJson = noteDir.resolveFile("note.json", NameScope.CHILD); if (!noteJson.exists()) { throw new IOException(noteJson.getName().toString() + " not found"); } GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setPrettyPrinting(); Gson gson = gsonBuilder.create(); FileContent content = noteJson.getContent(); InputStream ins = content.getInputStream(); String json = IOUtils.toString(ins, conf.getString(ConfVars.ZEPPELIN_ENCODING)); ins.close(); Note note = gson.fromJson(json, Note.class); // note.setReplLoader(replLoader); // note.jobListenerFactory = jobListenerFactory; for (Paragraph p : note.getParagraphs()) { if (p.getStatus() == Status.PENDING || p.getStatus() == Status.RUNNING) { p.setStatus(Status.ABORT); } } return note; } private NoteInfo getNoteInfo(FileObject noteDir) throws IOException { Note note = getNote(noteDir); return new NoteInfo(note); } @Override public Note get(String noteId) throws IOException { FileObject rootDir = fsManager.resolveFile(getPath("/")); FileObject projectDir = rootDir.resolveFile(this.project.getName(), NameScope.CHILD); FileObject noteDir = projectDir.resolveFile(noteId, NameScope.CHILD); if (noteDir.exists() && isDirectory(noteDir)) { return getNote(noteDir); } noteDir = rootDir.resolveFile(noteId, NameScope.CHILD); return getNote(noteDir); } private FileObject getRootDir() throws IOException { FileObject rootDir = fsManager.resolveFile(getPath("/")); if (!rootDir.exists()) { throw new IOException("Root path does not exists"); } if (!isDirectory(rootDir)) { throw new IOException("Root path is not a directory"); } return rootDir; } @Override public void save(Note note) throws IOException { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setPrettyPrinting(); Gson gson = gsonBuilder.create(); String json = gson.toJson(note); FileObject rootDir = getRootDir(); FileObject projectDir = rootDir.resolveFile(this.project.getName(), NameScope.CHILD); if (!projectDir.exists()) { projectDir.createFolder(); } if (!isDirectory(projectDir)) { throw new IOException(projectDir.getName().toString() + " is not a directory"); } FileObject noteDir = projectDir.resolveFile(note.id(), NameScope.CHILD); if (!noteDir.exists()) { noteDir.createFolder(); } if (!isDirectory(noteDir)) { throw new IOException(noteDir.getName().toString() + " is not a directory"); } FileObject noteJson = noteDir.resolveFile("note.json", NameScope.CHILD); // false means not appending. creates file if not exists OutputStream out = noteJson.getContent().getOutputStream(false); out.write(json.getBytes(conf.getString(ConfVars.ZEPPELIN_ENCODING))); out.close(); } @Override public void remove(String noteId) throws IOException { FileObject rootDir = fsManager.resolveFile(getPath("/")); FileObject projectDir = rootDir.resolveFile(this.project.getName(), NameScope.CHILD); if (!projectDir.exists() || !isDirectory(projectDir)) { // no project dir return; } FileObject noteDir = projectDir.resolveFile(noteId, NameScope.CHILD); if (!noteDir.exists()) { // nothing to do return; } if (!isDirectory(noteDir)) { // it is not look like zeppelin note savings throw new IOException("Can not remove " + noteDir.getName().toString()); } noteDir.delete(Selectors.SELECT_SELF_AND_CHILDREN); } }