1 /*
   2  *  Copyright (c) 2018, 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 
  24 package com.sun.tools.jextract;
  25 
  26 import java.io.*;
  27 import java.nio.file.Files;
  28 import java.nio.file.Path;
  29 import java.util.Arrays;
  30 import java.util.Map;
  31 import java.util.Properties;
  32 import java.util.logging.Level;
  33 
  34 public final class Writer {
  35 
  36     private final Log log;
  37     private final Map<String, byte[]> results;
  38 
  39     Writer(Context ctx, Map<String, byte[]> results) {
  40         this.log = ctx.log;
  41         this.results = results;
  42     }
  43 
  44     static final String JEXTRACT_MANIFEST = "META-INF/jextract.properties";
  45 
  46     public boolean isEmpty() {
  47         return results.isEmpty();
  48     }
  49 
  50     @SuppressWarnings("deprecation")
  51     byte[] getJextractProperties(String[] args) {
  52         Properties props = new Properties();
  53         props.setProperty("os.name", System.getProperty("os.name"));
  54         props.setProperty("os.version", System.getProperty("os.version"));
  55         props.setProperty("os.arch", System.getProperty("os.arch"));
  56         props.setProperty("jextract.args", Arrays.toString(args));
  57         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  58         props.save(baos, "jextract meta data");
  59         return baos.toByteArray();
  60     }
  61 
  62     void writeClassFiles(Path destDir, String[] args) throws IOException {
  63         try {
  64             results.forEach((cls, bytes) -> {
  65                 try {
  66                     String path = cls.replace('.', File.separatorChar) + ".class";
  67                     log.print(Level.FINE, () -> "Writing " + path);
  68                     Path fullPath = destDir.resolve(path).normalize();
  69                     Files.createDirectories(fullPath.getParent());
  70                     try (OutputStream fos = Files.newOutputStream(fullPath)) {
  71                         fos.write(bytes);
  72                         fos.flush();
  73                     }
  74                 } catch (IOException ioe) {
  75                     throw new UncheckedIOException(ioe);
  76                 }
  77             });
  78 
  79             Path propsPath = destDir.resolve(JEXTRACT_MANIFEST.replace('/', File.separatorChar)).normalize();
  80             Files.createDirectories(propsPath.getParent());
  81             try (OutputStream fos = Files.newOutputStream(propsPath)) {
  82                 fos.write(getJextractProperties(args));
  83                 fos.flush();
  84             }
  85         } catch (UncheckedIOException uioe) {
  86             throw uioe.getCause();
  87         }
  88     }
  89 
  90     //These methods are used for testing (see Runner.java)
  91 
  92     public Map<String, byte[]> results() {
  93         return results;
  94     }
  95 }