/* * Copyright (C) 2018-2021, Andre Bossert * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at * https://www.eclipse.org/org/documents/edl-v10.php. * * SPDX-License-Identifier: BSD-3-Clause */ package org.eclipse.jgit.internal.diffmergetool; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.lib.ObjectStream; /** * The element used as left or right file for compare. * */ public class FileElement { private final String path; private final String id; private ObjectStream stream; private File tempFile; /** * @param path * the file path * @param id * the file id */ public FileElement(final String path, final String id) { this(path, id, null); } /** * @param path * the file path * @param id * the file id * @param stream * the object stream to load instead of file */ public FileElement(final String path, final String id, ObjectStream stream) { this.path = path; this.id = id; this.stream = stream; } /** * @return the file path */ public String getPath() { return path; } /** * @return the file id */ public String getId() { return id; } /** * @param stream * the object stream */ public void setStream(ObjectStream stream) { this.stream = stream; } /** * Returns a temporary file with in passed working directory and fills it * with stream if valid. * * @param directory * the working directory where the temporary file is created * @param midName * name added in the middle of generated temporary file name * @return the object stream * @throws IOException */ public File getFile(File directory, String midName) throws IOException { if (tempFile != null) { return tempFile; } String[] fileNameAndExtension = splitBaseFileNameAndExtension( new File(path)); tempFile = File.createTempFile( fileNameAndExtension[0] + "_" + midName + "_", //$NON-NLS-1$ //$NON-NLS-2$ fileNameAndExtension[1], directory); copyFromStream(); return tempFile; } /** * Returns a real file from work tree or a temporary file with content if * stream is valid or if path is "/dev/null" * * @return the object stream * @throws IOException */ public File getFile() throws IOException { if (tempFile != null) { return tempFile; } File file = new File(path); String name = file.getName(); // if we have a stream or file is missing ("/dev/null") then create // temporary file if ((stream != null) || path.equals(DiffEntry.DEV_NULL)) { // TODO: avoid long random file name (number generated by // createTempFile) tempFile = File.createTempFile(".__", "__" + name); //$NON-NLS-1$ //$NON-NLS-2$ copyFromStream(); return tempFile; } return file; } /** * Deletes and invalidates temporary file if necessary. */ public void cleanTemporaries() { if (tempFile != null && tempFile.exists()) tempFile.delete(); tempFile = null; } private void copyFromStream() throws IOException, FileNotFoundException { if (stream != null) { try (OutputStream outStream = new FileOutputStream(tempFile)) { int read = 0; byte[] bytes = new byte[8 * 1024]; while ((read = stream.read(bytes)) != -1) { outStream.write(bytes, 0, read); } } finally { // stream can only be consumed once --> close it stream.close(); stream = null; } } } private static String[] splitBaseFileNameAndExtension(File file) { String[] result = new String[2]; result[0] = file.getName(); result[1] = ""; //$NON-NLS-1$ if (!result[0].startsWith(".")) { //$NON-NLS-1$ int idx = result[0].lastIndexOf("."); //$NON-NLS-1$ if (idx != -1) { result[1] = result[0].substring(idx, result[0].length()); result[0] = result[0].substring(0, idx); } } return result; } }