001    /*
002     * Copyright 2005 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.vafer.jdeb.producers;
017    
018    import java.io.File;
019    import java.io.FileInputStream;
020    import java.io.IOException;
021    import java.io.InputStream;
022    
023    import org.apache.tools.ant.DirectoryScanner;
024    import org.apache.tools.tar.TarEntry;
025    import org.vafer.jdeb.DataConsumer;
026    import org.vafer.jdeb.DataProducer;
027    import org.vafer.jdeb.mapping.Mapper;
028    import org.vafer.jdeb.utils.Utils;
029    
030    /**
031     * DataProducer iterating over a directory.
032     * For cross-platform permissions and ownerships you probably want to use a Mapper, too. 
033     * 
034     * @author Torsten Curdt <tcurdt@vafer.org>
035     */
036    public final class DataProducerDirectory extends AbstractDataProducer implements DataProducer {
037    
038            private final DirectoryScanner scanner = new DirectoryScanner();
039            
040            public DataProducerDirectory( final File pDir, final String[] pIncludes, final String[] pExcludes, final Mapper[] pMappers ) {
041                    super(pIncludes, pExcludes, pMappers);
042                    scanner.setBasedir(pDir);
043                    scanner.setIncludes(pIncludes);
044                    scanner.setExcludes(pExcludes);
045                    scanner.setCaseSensitive(true);
046                    scanner.setFollowSymlinks(true);
047            }
048            
049            public void produce( final DataConsumer receiver ) throws IOException {
050    
051                    scanner.scan();
052    
053                    final File baseDir = scanner.getBasedir();
054    
055                    final String[] dirs = scanner.getIncludedDirectories();
056                    for (int i = 0; i < dirs.length; i++) {
057                            final File file = new File(baseDir, dirs[i]);
058                            String dirname = getFilename(baseDir, file);
059    
060                            if ("".equals(dirname)) {
061                                    continue;
062                            }
063    
064                            if (!isIncluded(dirname)) {
065                                    continue;
066                            }
067    
068                            if ('/' != File.separatorChar) {
069                                    dirname = dirname.replace(File.separatorChar, '/');
070                            }
071    
072                            TarEntry entry = new TarEntry(dirname);
073                            entry.setUserId(0);
074                            entry.setUserName("root");
075                            entry.setGroupId(0);
076                            entry.setGroupName("root");
077                            entry.setMode(TarEntry.DEFAULT_DIR_MODE);
078    
079                            entry = map(entry);
080    
081                            entry.setSize(0);
082    
083                            receiver.onEachDir(entry.getName(), entry.getLinkName(), entry.getUserName(), entry.getUserId(), entry.getGroupName(), entry.getGroupId(), entry.getMode(), entry.getSize());
084                    }
085    
086    
087                    final String[] files = scanner.getIncludedFiles();
088    
089                    for (int i = 0; i < files.length; i++) {
090                            final File file = new File(baseDir, files[i]);
091                            String filename = getFilename(baseDir, file);
092    
093                            if (!isIncluded(filename)) {
094                                    continue;
095                            }
096    
097                            if ('/' != File.separatorChar) {
098                                    filename = filename.replace(File.separatorChar, '/');
099                            }
100    
101                            TarEntry entry = new TarEntry(filename);
102                            entry.setUserId(0);
103                            entry.setUserName("root");
104                            entry.setGroupId(0);
105                            entry.setGroupName("root");
106                            entry.setMode(TarEntry.DEFAULT_FILE_MODE);
107    
108                            entry = map(entry);
109    
110                            entry.setSize(file.length());
111    
112                            final InputStream inputStream = new FileInputStream(file);
113                            try {
114                                    receiver.onEachFile(inputStream, entry.getName(), entry.getLinkName(), entry.getUserName(), entry.getUserId(), entry.getGroupName(), entry.getGroupId(), entry.getMode(), entry.getSize());
115                            } finally {
116                                    inputStream.close();
117                            }
118                    }
119            }
120    
121            private String getFilename( File root, File file ) {
122                    
123                    final String relativeFilename = file.getAbsolutePath().substring(root.getAbsolutePath().length());              
124                    
125                    return Utils.stripLeadingSlash(relativeFilename);
126            }
127    
128    }