| /* | |
| * Copyright (C) 2012 Google Inc. and others | |
| * | |
| * 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.archive; | |
| import java.io.IOException; | |
| import java.io.OutputStream; | |
| import java.text.MessageFormat; | |
| import java.util.Arrays; | |
| import java.util.Collections; | |
| import java.util.List; | |
| import java.util.Map; | |
| import org.apache.commons.compress.archivers.ArchiveOutputStream; | |
| import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; | |
| import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; | |
| import org.eclipse.jgit.api.ArchiveCommand; | |
| import org.eclipse.jgit.archive.internal.ArchiveText; | |
| import org.eclipse.jgit.lib.FileMode; | |
| import org.eclipse.jgit.lib.ObjectId; | |
| import org.eclipse.jgit.lib.ObjectLoader; | |
| import org.eclipse.jgit.revwalk.RevCommit; | |
| /** | |
| * PKWARE's ZIP format. | |
| */ | |
| public final class ZipFormat extends BaseFormat implements | |
| ArchiveCommand.Format<ArchiveOutputStream> { | |
| private static final List<String> SUFFIXES = Collections | |
| .unmodifiableList(Arrays.asList(".zip")); //$NON-NLS-1$ | |
| @Override | |
| public ArchiveOutputStream createArchiveOutputStream(OutputStream s) | |
| throws IOException { | |
| return createArchiveOutputStream(s, | |
| Collections.<String, Object> emptyMap()); | |
| } | |
| @Override | |
| public ArchiveOutputStream createArchiveOutputStream(OutputStream s, | |
| Map<String, Object> o) throws IOException { | |
| ZipArchiveOutputStream out = new ZipArchiveOutputStream(s); | |
| int compressionLevel = getCompressionLevel(o); | |
| if (compressionLevel != -1) { | |
| out.setLevel(compressionLevel); | |
| } | |
| return applyFormatOptions(out, o); | |
| } | |
| @Override | |
| public void putEntry(ArchiveOutputStream out, | |
| ObjectId tree, String path, FileMode mode, ObjectLoader loader) | |
| throws IOException { | |
| // ZipArchiveEntry detects directories by checking | |
| // for '/' at the end of the filename. | |
| if (path.endsWith("/") && mode != FileMode.TREE) //$NON-NLS-1$ | |
| throw new IllegalArgumentException(MessageFormat.format( | |
| ArchiveText.get().pathDoesNotMatchMode, path, mode)); | |
| if (!path.endsWith("/") && mode == FileMode.TREE) //$NON-NLS-1$ | |
| path = path + "/"; //$NON-NLS-1$ | |
| final ZipArchiveEntry entry = new ZipArchiveEntry(path); | |
| if (tree instanceof RevCommit) { | |
| long t = ((RevCommit) tree).getCommitTime() * 1000L; | |
| entry.setTime(t); | |
| } | |
| if (mode == FileMode.TREE) { | |
| out.putArchiveEntry(entry); | |
| out.closeArchiveEntry(); | |
| return; | |
| } | |
| if (mode == FileMode.REGULAR_FILE) { | |
| // ok | |
| } else if (mode == FileMode.EXECUTABLE_FILE | |
| || mode == FileMode.SYMLINK) { | |
| entry.setUnixMode(mode.getBits()); | |
| } else { | |
| // Unsupported mode (e.g., GITLINK). | |
| throw new IllegalArgumentException(MessageFormat.format( | |
| ArchiveText.get().unsupportedMode, mode)); | |
| } | |
| entry.setSize(loader.getSize()); | |
| out.putArchiveEntry(entry); | |
| loader.copyTo(out); | |
| out.closeArchiveEntry(); | |
| } | |
| @Override | |
| public Iterable<String> suffixes() { | |
| return SUFFIXES; | |
| } | |
| @Override | |
| public boolean equals(Object other) { | |
| return (other instanceof ZipFormat); | |
| } | |
| @Override | |
| public int hashCode() { | |
| return getClass().hashCode(); | |
| } | |
| } |