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 }