
ai.h2o.mojos.runtime.readers.MojoReaderBackend Maven / Gradle / Ivy
package ai.h2o.mojos.runtime.readers;
import ai.h2o.mojos.runtime.api.backend.ReaderBackend;
import ai.h2o.mojos.runtime.api.backend.ReaderBackendUtils;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* Interface representing a class capable of reading mojos. Usually the class
* implementing this interface will have a constructor taking an "address" of
* the mojo file that should be read. The class would then have to implement
* the logic for reading the referred mojo from the source.
*
* For example, a hypothetical MysqlMojoReaderBackend
may have
* a constructor taking the URL of the server, connection credentials, and
* a SQL query for retrieving the mojo record. The class would then implement
* the logic for connecting to the database and fetching the mojo (whole or in
* parts). It would also throw an {@link IOException} if anything fails.
*
* The actual interface that the class needs to implement is for reading either
* text or binary fragments from within the mojo. This is because a
* .mojo
file is actually a zip archive, and hence it contains
* several "files" inside. The user may decide to repackage the mojo contents
* into a different container: a plain directory for easier access, a
* .7z
file for better compression, an encrypted Zip file for
* better security, etc. If the reader doesn't wish to re-package the mojo
* contents and only retrieve it from non-filesystem source, then it may
* create a temporary .mojo file and pass it to the
* {@link MojofileMojoReaderBackend} reader.
*/
/**
* @deprecated use {@link ReaderBackend} instead.
*/
@Deprecated
public abstract class MojoReaderBackend implements Closeable {
private String _pipelineFileName;
private String _baseDir;
/**
* Default top-level directory, where mojo content is stored.
*/
public static String DEFAULT_BASE_DIR = "mojo/";
/* Default name of protobuffer-based pipeline */
public static String DEFAULT_PROTO_PIPELINE_FILENAME = "pipeline.pb";
/* Default name of TOML-based pipeline */
public static String DEFAULT_TOML_PIPELINE_FILENAME = "pipeline.toml";
/**
* Default file path for proto-based pipeline
*/
public static String DEFAULT_PROTO_PIPELINE_FILE_PATH = DEFAULT_BASE_DIR + DEFAULT_PROTO_PIPELINE_FILENAME;
/**
* Default file path for toml-based pipeline
*/
public static String DEFAULT_TOML_PIPELINE_FILE_PATH = DEFAULT_BASE_DIR + DEFAULT_TOML_PIPELINE_FILENAME;
protected final ReaderBackend backend;
protected MojoReaderBackend(ReaderBackend backend, String baseDir, String ignored, String pipelineFileName) {
this.backend = backend;
_pipelineFileName = pipelineFileName == null
? (baseDir == null
? DEFAULT_PROTO_PIPELINE_FILE_PATH
: DEFAULT_PROTO_PIPELINE_FILENAME)
: pipelineFileName;
if (baseDir == null) {
_baseDir = "";
} else {
if (baseDir.isEmpty() || endsWithSeparator(baseDir)) {
_baseDir = baseDir;
} else {
_baseDir = baseDir + "/";
}
}
}
@Override
public final void close() throws IOException {
backend.close();
}
/**
* Retrieve content inside the mojo, as a {@link InputStream}.
*/
public final InputStream getFile(String filename) throws IOException {
return backend.getInputStream(filename);
}
/**
* Retrieve text content inside the mojo, as a {@link BufferedReader}.
*/
public final BufferedReader getTextFile(String filename) throws IOException {
return ReaderBackendUtils.asReader(backend.getInputStream(filename));
}
/**
* Retrieve binary content inside the mojo, as a byte[]
array.
*/
public final byte[] getBinaryFile(String filename) throws IOException {
return ReaderBackendUtils.getBytes(backend.getInputStream(filename));
}
public final boolean exists(String filename) {
return backend.exists(filename);
}
/**
* Do not use. Not useful outside mojo2 project.
* Exists only for retaining API compatibility inside mojo2 classes, and will be removed
* in future versions, without notice, deprecation phase and replacement.
*/
public ReaderBackend internalGetReaderBackend() {
return this.backend;
}
/**
* Get pipeline file path relative to baseDir.
*/
public String getPipelineFileName() {
return _pipelineFileName;
}
public String getBaseDir() {
return _baseDir;
}
/**
* @deprecated use just slash (/
) instead, it is supported on all systems equally well, or use {@link File#separator} if that makes you feel better
*/
@Deprecated
public String getSeparator() {
return "/";
}
/**
* This is very safe way to check if a path ends with separator character, no matter which platform was used to produce the path
* and which platform we use it on.
*
* @param path -
* @return true if the last character is separator
*/
public static boolean endsWithSeparator(String path) {
if (path == null) return false;
if (path.isEmpty()) return false;
final char lastChar = path.charAt(path.length() - 1);
switch (lastChar) {
case '/':
case '\\':
return true;
}
return lastChar == File.separatorChar;
}
}