001    /*
002     *  Licensed under the Apache License, Version 2.0 (the "License");
003     *  you may not use this file except in compliance with the License.
004     *  You may obtain a copy of the License at
005     *
006     *      http://www.apache.org/licenses/LICENSE-2.0
007     *
008     *  Unless required by applicable law or agreed to in writing, software
009     *  distributed under the License is distributed on an "AS IS" BASIS,
010     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011     *  See the License for the specific language governing permissions and
012     *  limitations under the License.
013     */
014    /*
015     * This file has been modified by Chris Pheby in accordance with Section 4.2
016     * of the Apache Software License
017     */
018    package org.jadira.repositorysnapshot;
019    
020    import java.io.BufferedOutputStream;
021    import java.io.File;
022    import java.io.FileInputStream;
023    import java.io.FileOutputStream;
024    import java.io.IOException;
025    import java.util.zip.Deflater;
026    import java.util.zip.ZipEntry;
027    import java.util.zip.ZipException;
028    import java.util.zip.ZipOutputStream;
029    
030    import org.jadira.dependencynavigator.gui.ProgressMeter;
031    import org.jadira.dependencynavigator.implementations.zip.ZipFileRepository;
032    import org.jadira.dependencynavigator.implementations.zip.ZipFileWorkspace;
033    
034    public class RepositorySnapshot {
035    
036        private final File snapshotFile;
037        private final File repositoryRoot;
038        private final File workspace;
039    
040        public RepositorySnapshot(File repositoryRoot, File snapshotFile, File workspace) {
041            this.repositoryRoot = repositoryRoot;
042            this.snapshotFile = snapshotFile;
043            this.workspace = workspace;
044        }
045    
046        public void createSnapshot(ProgressMeter progressMeter) throws ZipException, IOException {
047            snapshotFile.delete();
048            snapshotFile.getParentFile().mkdirs();
049            snapshotFile.createNewFile();
050            ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(snapshotFile)));
051            out.setLevel(Deflater.BEST_COMPRESSION);
052            out.setMethod(ZipOutputStream.DEFLATED);
053    
054            HierarchyFilter workspaceFilter = new HierarchyFilter() {
055    
056                @Override
057                public boolean includeDirectory(File directory) throws IOException {
058                    if (directory.getName().equals(".metadata")) {
059                        return false;
060                    }
061                    if (directory.getCanonicalPath().equals(repositoryRoot.getCanonicalPath())) {
062                        return false;
063                    }
064                    return true;
065                }
066    
067            };
068    
069            addHeirarchy(workspace, out, ZipFileWorkspace.PREFIX_WORKSPACE, workspaceFilter, progressMeter);
070    
071            HierarchyFilter repositoryFilter = new HierarchyFilter() {
072    
073                @Override
074                public boolean includeFile(File file) throws IOException {
075                    if (!file.getName().endsWith(".pom")) {
076                        // excude non-pom files
077                        return false;
078                    }
079                    if (file.getName().matches("^.*-\\d{8}\\.\\d{6}-\\d+\\.pom$")) {
080                        // exclude snapshot builds
081                        return false;
082                    }
083                    return true;
084                }
085    
086            };
087    
088            addHeirarchy(repositoryRoot, out, ZipFileRepository.PREFIX_REPOSITORY, repositoryFilter, progressMeter);
089            out.close();
090        }
091    
092        private void addHeirarchy(File directory, ZipOutputStream out, String repoPath, HierarchyFilter filter, ProgressMeter progressMeter) throws IOException {
093            File[] files = directory.listFiles();
094            for (int i = 0; i < files.length; i++) {
095                File file = files[i];
096                if (file.isDirectory() && filter.includeDirectory(file)) {
097                    progressMeter.scanning(file);
098                    addHeirarchy(file, out, repoPath + "/" + file.getName(), filter, progressMeter);
099                } else {
100                    if (filter.includeFile(file)) {
101                        progressMeter.adding(file);
102                        addEntry(file, repoPath + "/" + file.getName(), out);
103                    }
104                }
105            }
106        }
107    
108        private class HierarchyFilter {
109    
110            public boolean includeFile(File file) throws IOException {
111                return file.getName().equals("pom.xml");
112            }
113    
114            public boolean includeDirectory(File directory) throws IOException {
115                return true;
116            }
117        }
118    
119        private void addEntry(File target, String repoPath, ZipOutputStream out) throws IOException {
120            ZipEntry entry = new ZipEntry(repoPath);
121            int fileLength = (int) target.length();
122            FileInputStream fis = new FileInputStream(target);
123            byte[] wholeFile = new byte[fileLength];
124            fis.read(wholeFile, 0, fileLength);
125            fis.close();
126            out.putNextEntry(entry);
127            out.write(wholeFile, 0, fileLength);
128            out.closeEntry();
129        }
130    }