All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.calcite.adapter.os.Processes Maven / Gradle / Ivy

The newest version!
/*
 * 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.calcite.adapter.os;

import org.apache.calcite.linq4j.AbstractEnumerable;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.linq4j.Enumerator;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.function.Supplier;

import static java.util.Objects.requireNonNull;

/**
 * Utilities regarding operating system processes.
 *
 * 

WARNING: Spawning processes is not secure. * Use this class with caution. * This class is in the "plus" module because "plus" is not used by default. * Do not move this class to the "core" module. */ public class Processes { private Processes() {} /** Executes a command and returns its result as an enumerable of lines. */ static Enumerable processLines(String... args) { return processLines(' ', args); } /** Executes a command and returns its result as an enumerable of lines. */ static Enumerable processLines(char sep, String... args) { return processLines(sep, processSupplier(args)); } /** Executes a command and returns its result as an enumerable of lines. * * @param sep Separator character * @param processSupplier Command and its arguments */ private static Enumerable processLines(char sep, Supplier processSupplier) { if (sep != ' ') { return new SeparatedLinesEnumerable(processSupplier, sep); } else { return new ProcessLinesEnumerator(processSupplier); } } private static Supplier processSupplier(final String... args) { return new ProcessFactory(args); } /** Enumerator that executes a process and returns each line as an element. */ private static class ProcessLinesEnumerator extends AbstractEnumerable { private final Supplier processSupplier; ProcessLinesEnumerator(Supplier processSupplier) { this.processSupplier = requireNonNull(processSupplier, "processSupplier"); } @Override public Enumerator enumerator() { final Process process = processSupplier.get(); final InputStream is = process.getInputStream(); final BufferedInputStream bis = new BufferedInputStream(is); final InputStreamReader isr = new InputStreamReader(bis, StandardCharsets.UTF_8); final BufferedReader br = new BufferedReader(isr); return new Enumerator() { private String line; @Override public String current() { return line; } @Override public boolean moveNext() { try { line = br.readLine(); return line != null; } catch (IOException e) { throw new RuntimeException(e); } } @Override public void reset() { throw new UnsupportedOperationException(); } @Override public void close() { try { br.close(); } catch (IOException e) { throw new RuntimeException("while running " + processSupplier, e); } process.destroy(); } }; } } /** Enumerator that executes a process and returns each line as an element. */ private static class SeparatedLinesEnumerable extends AbstractEnumerable { private final Supplier processSupplier; private final int sep; SeparatedLinesEnumerable(Supplier processSupplier, char sep) { this.processSupplier = processSupplier; this.sep = sep; } @Override public Enumerator enumerator() { final Process process = processSupplier.get(); final InputStream is = process.getInputStream(); final BufferedInputStream bis = new BufferedInputStream(is); final InputStreamReader isr = new InputStreamReader(bis, StandardCharsets.UTF_8); final BufferedReader br = new BufferedReader(isr); return new Enumerator() { private final StringBuilder b = new StringBuilder(); private String line; @Override public String current() { return line; } @Override public boolean moveNext() { try { for (;;) { int c = br.read(); if (c < 0) { return false; } if (c == sep) { line = b.toString(); b.setLength(0); return true; } b.append((char) c); } } catch (IOException e) { throw new RuntimeException(e); } } @Override public void reset() { throw new UnsupportedOperationException(); } @Override public void close() { try { br.close(); } catch (IOException e) { throw new RuntimeException("while running " + processSupplier, e); } process.destroy(); } }; } } /** Creates processes. */ private static class ProcessFactory implements Supplier { private final String[] args; ProcessFactory(String... args) { this.args = args; } @Override public Process get() { try { return new ProcessBuilder().command(args).start(); } catch (IOException e) { throw new RuntimeException("while creating process: " + Arrays.toString(args), e); } } @Override public String toString() { return args[0]; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy