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; } }