Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2012-2013 the original author or authors.
   *
   * Licensed 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.springframework.boot.loader.tools;
 
 import java.io.File;
 import java.net.URL;
 import java.util.Set;
Writes JAR content, ensuring valid directory entries are always create and duplicate items are ignored.

Author(s):
Phillip Webb
Andy Wilkinson
 
 public class JarWriter {
 
 	private static final String NESTED_LOADER_JAR = "META-INF/loader/spring-boot-loader.jar";
 
 	private static final int BUFFER_SIZE = 32 * 1024;
 
 	private final JarOutputStream jarOutput;
 
 	private final Set<StringwrittenEntries = new HashSet<String>();

Create a new JarWriter instance.

Parameters:
file the file to write
Throws:
java.io.IOException
java.io.FileNotFoundException
 
 	public JarWriter(File filethrows FileNotFoundExceptionIOException {
 		this. = new JarOutputStream(new FileOutputStream(file));
 	}

Write the specified manifest.

Parameters:
manifest the manifest to write
Throws:
java.io.IOException
 
 	public void writeManifest(final Manifest manifestthrows IOException {
 		JarEntry entry = new JarEntry("META-INF/MANIFEST.MF");
 		writeEntry(entrynew EntryWriter() {
 			public void write(OutputStream outputStreamthrows IOException {
 				manifest.write(outputStream);
 			}
 		});
 	}

Write all entries from the specified jar file.

Parameters:
jarFile the source jar file
Throws:
java.io.IOException
 
 	public void writeEntries(JarFile jarFilethrows IOException {
 		Enumeration<JarEntryentries = jarFile.entries();
 		while (entries.hasMoreElements()) {
 			JarEntry entry = entries.nextElement();
 					jarFile.getInputStream(entry));
 			try {
 				if (inputStream.hasZipHeader() && entry.getMethod() != .) {
 					new CrcAndSize(inputStream).setupStoredEntry(entry);
 					inputStream.close();
 					inputStream = new ZipHeaderPeekInputStream(
							jarFile.getInputStream(entry));
				}
				EntryWriter entryWriter = new InputStreamEntryWriter(inputStreamtrue);
				writeEntry(entryentryWriter);
			}
			finally {
				inputStream.close();
			}
		}
	}

Writes an entry. The inputStream is closed once the entry has been written

Parameters:
entryName The name of the entry
inputStream The stream from which the entry's data can be read
Throws:
java.io.IOException if the write fails
	public void writeEntry(String entryNameInputStream inputStreamthrows IOException {
		JarEntry entry = new JarEntry(entryName);
		writeEntry(entrynew InputStreamEntryWriter(inputStreamtrue));
	}

Write a nested library.

Parameters:
destination the destination of the library
library the library
Throws:
java.io.IOException if the write fails
	public void writeNestedLibrary(String destinationLibrary library)
			throws IOException {
		File file = library.getFile();
		JarEntry entry = new JarEntry(destination + library.getName());
		if (library.isUnpackRequired()) {
			entry.setComment("UNPACK:" + FileUtils.sha1Hash(file));
		}
		new CrcAndSize(file).setupStoredEntry(entry);
		writeEntry(entrynew InputStreamEntryWriter(new FileInputStream(file), true));
	}

Write the required spring-boot-loader classes to the JAR.

	public void writeLoaderClasses() throws IOException {
				loaderJar.openStream()));
		JarEntry entry;
		while ((entry = inputStream.getNextJarEntry()) != null) {
			if (entry.getName().endsWith(".class")) {
				writeEntry(entrynew InputStreamEntryWriter(inputStreamfalse));
			}
		}
		inputStream.close();
	}

Close the writer.

	public void close() throws IOException {
	}

Perform the actual write of a java.util.jar.JarEntry. All other write method delegate to this one.

Parameters:
entry the entry to write
entryWriter the entry writer or null if there is no content
Throws:
java.io.IOException
	private void writeEntry(JarEntry entryEntryWriter entryWriterthrows IOException {
		String parent = entry.getName();
		if (parent.endsWith("/")) {
			parent = parent.substring(0, parent.length() - 1);
		}
		if (parent.lastIndexOf("/") != -1) {
			parent = parent.substring(0, parent.lastIndexOf("/") + 1);
			if (parent.length() > 0) {
				writeEntry(new JarEntry(parent), null);
			}
		}
		if (this..add(entry.getName())) {
			if (entryWriter != null) {
				entryWriter.write(this.);
			}
		}
	}

Interface used to write jar entry date.
	private static interface EntryWriter {

Write entry data to the specified output stream

Parameters:
outputStream the destination for the data
Throws:
java.io.IOException
		void write(OutputStream outputStreamthrows IOException;
	}

JarWriter.EntryWriter that writes content from an java.io.InputStream.
	private static class InputStreamEntryWriter implements EntryWriter {
		private final InputStream inputStream;
		private final boolean close;
		public InputStreamEntryWriter(InputStream inputStreamboolean close) {
			this. = inputStream;
			this. = close;
		}
		public void write(OutputStream outputStreamthrows IOException {
			byte[] buffer = new byte[];
			int bytesRead = -1;
			while ((bytesRead = this..read(buffer)) != -1) {
				outputStream.write(buffer, 0, bytesRead);
			}
			outputStream.flush();
			if (this.) {
			}
		}
	}

java.io.InputStream that can peek ahead at zip header bytes.
	private static class ZipHeaderPeekInputStream extends FilterInputStream {
		private static final byte[] ZIP_HEADER = new byte[] { 0x50, 0x4b, 0x03, 0x04 };
		private final byte[] header;
			super(in);
			this. = new byte[4];
			int len = in.read(this.);
			this. = new ByteArrayInputStream(this., 0, len);
		}
		public int read() throws IOException {
			int read = (this. == null ? -1 : this..read());
			if (read != -1) {
				this. = null;
				return read;
			}
			return super.read();
		}
		public int read(byte[] bthrows IOException {
			return read(b, 0, b.length);
		}
		public int read(byte[] bint offint lenthrows IOException {
			int read = (this. == null ? -1 : this..read(boff,
					len));
			if (read != -1) {
				this. = null;
				return read;
			}
			return super.read(bofflen);
		}
		public boolean hasZipHeader() {
			return Arrays.equals(this.);
		}
	}

Data holder for CRC and Size
	private static class CrcAndSize {
		private final CRC32 crc = new CRC32();
		private long size;
		public CrcAndSize(File filethrows IOException {
			FileInputStream inputStream = new FileInputStream(file);
			try {
				load(inputStream);
			}
			finally {
				inputStream.close();
			}
		}
		public CrcAndSize(InputStream inputStreamthrows IOException {
			load(inputStream);
		}
		private void load(InputStream inputStreamthrows IOException {
			byte[] buffer = new byte[];
			int bytesRead = -1;
			while ((bytesRead = inputStream.read(buffer)) != -1) {
				this..update(buffer, 0, bytesRead);
				this. += bytesRead;
			}
		}
		public void setupStoredEntry(JarEntry entry) {
			entry.setSize(this.);
			entry.setCrc(this..getValue());
		}
	}
New to GrepCode? Check out our FAQ X