/*
* Copyright 2011 Future Systems
*
* 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.krakenapps.filemon.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
import org.krakenapps.codec.EncodingRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BaselineBuilder {
private final Logger logger = LoggerFactory.getLogger(BaselineBuilder.class.getName());
private final File baseDir;
private Set<File> files;
private Set<File> paths;
private Set<Pattern> excludes;
public BaselineBuilder(Set<File> paths, Set<Pattern> excludes) {
this.baseDir = getBaseDirectory();
this.files = new TreeSet<File>();
this.paths = paths;
this.excludes = excludes;
for (File f : paths)
scan(f, excludes);
logger.trace("kraken filemon: set base directory [{}]", baseDir.getAbsolutePath());
}
private void scan(File f, Set<Pattern> excludes) {
if (f.isFile() && !isExcluded(excludes, f))
files.add(f);
if (f.isDirectory()) {
for (File entry : f.listFiles())
scan(entry, excludes);
}
}
private boolean isExcluded(Set<Pattern> excludes, File f) {
String path = f.getAbsolutePath();
for (Pattern p : excludes)
if (p.matcher(path).matches())
return true;
return false;
}
public Set<File> getTargetFiles() {
return files;
}
public File build() throws IOException {
File db = File.createTempFile("kraken-filemon-", ".db");
FileOutputStream os = new FileOutputStream(db);
try {
// write file headers
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("created", new Date());
headers.put("file_count", files.size());
headers.put("includes", marshalPaths());
headers.put("excludes", marshalExcludes());
int len = EncodingRule.lengthOf(headers);
ByteBuffer b = ByteBuffer.allocate(len);
EncodingRule.encode(b, headers);
os.write(b.array());
// write files
ByteBuffer bb = ByteBuffer.allocate(512);
for (File f : files) {
long fileSize = f.length();
long lastModified = f.lastModified();
boolean hidden = f.isHidden();
String hash = HashUtils.getSha1(f);
Object[] record = new Object[] { f.getAbsolutePath(), fileSize, lastModified, hidden, hash };
EncodingRule.encode(bb, record);
bb.flip();
os.write(bb.array(), 0, bb.limit());
bb.clear();
logger.trace("kraken filemon: adding file [{}] to baseline", f.getAbsolutePath());
}
return db;
} finally {
logger.trace("kraken filemon: baseline [{}] created", db.getAbsolutePath());
os.close();
File target = new File(baseDir, "kraken-filemon-baseline.db");
boolean deleted = target.delete();
if (!deleted)
logger.trace("kraken filemon: old baseline not removed");
db.renameTo(target);
logger.trace("kraken filemon: created baseline [{}]", target.getAbsolutePath());
}
}
private List<String> marshalPaths() {
List<String> l = new LinkedList<String>();
for (File f : paths)
l.add(f.getAbsolutePath());
return l;
}
private List<String> marshalExcludes() {
List<String> l = new LinkedList<String>();
for (Pattern p : excludes)
l.add(p.pattern());
return l;
}
private File getBaseDirectory() {
File dir = new File(System.getProperty("kraken.data.dir"), "kraken-filemon/");
dir.mkdirs();
return dir;
}
}