/*
* #!
* Ontopia Content Store
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* 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 net.ontopia.infoset.content;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.util.Arrays;
import java.util.Comparator;
/**
* INTERNAL: A utility class that analyzes a file content store
* directory and repairs the key file. WARNING: all applications using
* the file content store must be stopped before running this
* application.
*/
public class RepairKeyFile {
public static void main(String[] args) throws Exception {
File cstore = new File(args[0]);
File[] files = cstore.listFiles(new FileFilter() {
public boolean accept(File file) {
if (file.isDirectory()) {
String name = file.getName();
try {
int num = Integer.parseInt(name);
return true;
} catch (NumberFormatException e) {
return false;
}
}
return false;
}
});
Arrays.sort(files, new Comparator<File>() {
public int compare(File f1, File f2) {
int i1 = Integer.parseInt(f1.getName());
int i2 = Integer.parseInt(f2.getName());
return (i1 > i2 ? -1 : (i1 < i2 ? 1 : 0));
}
});
int dirval = 0;
if (files.length > 0) {
File maxdir = files[0];
dirval = Integer.parseInt(maxdir.getName());
}
// calculating existing key block
int key = dirval * FileContentStore.FILES_PER_DIRECTORY;
// calculating next key block by switching to new directory
key += FileContentStore.FILES_PER_DIRECTORY;
System.out.println("Allocating key block " + key + " in " + cstore);
allocateBlock(cstore, key);
}
private static void allocateBlock(File cstore, int new_key) throws ContentStoreException {
boolean exception_thrown = false;
File key_file = new File(cstore, "keyfile.txt");
RandomAccessFile out = null;
try {
out = new RandomAccessFile(key_file, "rw");
for (int i=0; i < FileContentStore.MAX_SPINS; i++) {
// acquire exclusive lock
FileLock l = out.getChannel().tryLock();
if (l == null) {
// wait a little before trying again
try {
Thread.sleep(FileContentStore.SPIN_TIMEOUT);
} catch (InterruptedException e) {
}
continue;
} else {
// truncate key file and write out new key
out.setLength(0);
out.writeUTF(Integer.toString(new_key));
return;
}
}
throw new ContentStoreException("Block allocation timed out.");
} catch (ContentStoreException e) {
exception_thrown = true;
throw e;
} catch (Throwable t) {
exception_thrown = true;
throw new ContentStoreException(t);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
if (!exception_thrown)
throw new ContentStoreException ("Problems occurred when closing content store.", e);
}
}
}
}
}