package org.basex.core.cmd;
import static org.basex.core.Text.*;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import org.basex.core.Command;
import org.basex.core.Prop;
import org.basex.core.User;
import org.basex.data.Data;
import org.basex.io.IO;
import org.basex.io.IOFile;
import org.basex.io.out.PrintOutput;
import org.basex.io.serial.Serializer;
import org.basex.io.serial.SerializerProp;
import org.basex.util.Token;
import org.basex.util.Util;
import org.basex.util.list.IntList;
/**
* Evaluates the 'export' command and saves the currently opened database
* to disk.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class Export extends Command {
/**
* Default constructor, specifying a target path.
* @param path export path
*/
public Export(final String path) {
super(DATAREF | User.CREATE, path);
}
@Override
protected boolean run() {
try {
final Data data = context.data();
export(data, args[0]);
return info(DB_EXPORTED_X, data.meta.name, perf);
} catch(final IOException ex) {
Util.debug(ex);
return error(ex.getMessage());
}
}
/**
* Exports the current database to the specified path.
* Files and directories in {@code path} will be possibly overwritten.
* @param data data reference
* @param target directory
* @throws IOException I/O exception
*/
public static void export(final Data data, final String target)
throws IOException {
final String exp = data.meta.prop.get(Prop.EXPORTER);
final SerializerProp sp = new SerializerProp(exp);
final IOFile root = new IOFile(target);
root.md();
final HashSet<String> exported = new HashSet<String>();
// export raw files
final IntList il = data.resources.docs();
for(int i = 0, is = il.size(); i < is; i++) {
final int pre = il.get(i);
// create file path
final IO file = root.merge(Token.string(data.text(pre, true)));
// create dir if necessary
final IOFile dir = new IOFile(file.dir());
if(!dir.exists()) dir.md();
// serialize file
final PrintOutput po = new PrintOutput(unique(exported, file.path()));
final Serializer ser = Serializer.get(po, sp);
ser.node(data, pre);
ser.close();
po.close();
}
// export raw files
final IOFile bin = data.meta.binaries();
for(final String s : bin.descendants()) {
final String u = unique(exported, new IOFile(root.path(), s).path());
Copy.copy(new File(bin.path(), s), new File(u));
}
}
/**
* Returns a unique file path.
* @param exp exported names
* @param fp file path
* @return unique path
*/
private static String unique(final HashSet<String> exp, final String fp) {
int c = 1;
String path = fp;
while(exp.contains(path)) {
path = fp.indexOf('.') == -1 ? fp + '(' + ++c + ')' :
fp.replaceAll("(.*)\\.(.*)", "$1(" + ++c + ").$2");
}
exp.add(path);
return path;
}
}