1 /*
  2  * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 package org.openjdk.asmtools.common;
 24 
 25 
 26 import java.io.DataInputStream;
 27 import java.io.FileInputStream;
 28 import java.io.IOException;
 29 import java.io.PrintWriter;
 30 import java.net.URI;
 31 import java.net.URISyntaxException;
 32 import java.net.URL;
 33 import java.net.URLConnection;
 34 import java.util.function.BooleanSupplier;
 35 import java.util.function.Consumer;
 36 
 37 public abstract class Tool {
 38 
 39     // Name of the program.
 40     protected final String programName;
 41     // Errors counter.
 42     protected int nerrors = 0;
 43     // The stream where error message are printed.
 44     protected PrintWriter err;
 45 
 46     // Output stream
 47     protected PrintWriter out;
 48 
 49     // A consumer to print a error message if the tool can't read a file
 50     protected Consumer<String> printCannotReadMsg;
 51 
 52     // A supplier to get a status of a debug flag
 53     protected BooleanSupplier DebugFlag = () -> false;
 54 
 55     public Tool(PrintWriter out, String programName) {
 56         this(out, out, programName);
 57     }
 58 
 59     public Tool(PrintWriter out, PrintWriter err, String programName) {
 60         this.out = out;
 61         this.err = err;
 62         this.programName = programName;
 63     }
 64 
 65 
 66     public String getError(String msg) {
 67         return programName + ": " + msg;
 68     }
 69 
 70     /**
 71      * Top level error message
 72      */
 73     public void error(String msg) {
 74         err.println(getError(msg));
 75         err.flush();
 76     }
 77 
 78     /**
 79      * Top level print message
 80      */
 81     public void println(String msg) {
 82         out.println(msg);
 83         out.flush();
 84     }
 85 
 86     public void println() {
 87         println("");
 88     }
 89 
 90     public void print(String msg) {
 91         out.print(getError(msg));
 92         out.flush();
 93     }
 94 
 95     /**
 96      * @param fname file name
 97      * @return DataInputStream or null if the method can't read a file
 98      */
 99     public DataInputStream getDataInputStream(String fname) {
100         try {
101             return new DataInputStream(new FileInputStream(fname));
102         } catch (IOException ex) {
103             if (fname.matches("^[A-Za-z]+:.*")) {
104                 try {
105                     final URI uri = new URI(fname);
106                     final URL url = uri.toURL();
107                     final URLConnection conn = url.openConnection();
108                     conn.setUseCaches(false);
109                     return new DataInputStream(conn.getInputStream());
110                 } catch (URISyntaxException | IOException e) {
111                     if (DebugFlag.getAsBoolean())
112                         e.printStackTrace();
113                 }
114             }
115             if (printCannotReadMsg != null)
116                 printCannotReadMsg.accept(fname);
117         }
118         return null;
119     }
120 
121     /**
122      * Usage
123      */
124     protected abstract void usage();
125 }