package entropy.vjob.queue; /* * Copyright (c) 2010 Ecole des Mines de Nantes. * * This file is part of Entropy. * * Entropy is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Entropy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Entropy. If not, see <http://www.gnu.org/licenses/>. */ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import entropy.vjob.VJob; import entropy.vjob.builder.VJobBuilder; import entropy.vjob.builder.VJobBuilderException; /** * A simple storable queue. All the vjobs are stored into a folder. * VJob can be added (removed) either using the add(remove) method, or * bu putting(deleting) the vjob in the folder. * * @author Fabien Hermenier */ public class FCFSPersistentQueue extends VJobsPool { /** * Compare the file by their modification date. Older first */ private static Comparator<File> olderFirst = new Comparator<File>() { @Override public int compare(File f1, File f2) { return (int) (f1.lastModified() - f2.lastModified()); } }; /** * The current directory that store VJobs. */ private File rootDir = new File("./vjobs"); /** * The extension of the file. */ public static final String EXTENSION = ".btrp"; /** * The builder to create the VJob from a file. */ private VJobBuilder builder; /** * Make a new queue. * If the folder describing the queue does not exists, it is created. * * @param b the builder that constructs VJobs * @param folder the folder where to store the vjobs. */ public FCFSPersistentQueue(VJobBuilder b, File folder) { builder = b; rootDir = folder; if (!rootDir.exists() && !rootDir.mkdirs()) { getLogger().info("Unable to create folder '" + folder + "'"); } } /** * Get the VJobs by browsing the folder. * * @return a list of vjobs, may be empty */ @Override public List<VJob> getRunningPriorities() { List<VJob> readed = new LinkedList<VJob>(); List<File> files = new ArrayList<File>(); for (File f : this.rootDir.listFiles()) { if (f.getName().endsWith(EXTENSION)) { files.add(f); } else { getLogger().debug("Ignoring '" + f.getName() + "'"); } } Collections.sort(files, olderFirst); for (File f : files) { try { VJob l = this.builder.build(removeExtension(f), f); readed.add(l); } catch (IOException e) { getLogger().debug("Skipping vJob in " + f.getName() + ": " + e.getMessage()); } catch (VJobBuilderException e) { getLogger().debug("Skipping vJob in " + f.getName() + ": " + e.getMessage()); } } return readed; } /** * Put the VJob in the queue folder. * * @param v the vjob to add * @return true if the vjob is stored into the queue folder. */ @Override public boolean add(VJob v) { try { v.store(new File(buildPath(v.id()))); } catch (IOException e) { getLogger().warn(e.getMessage()); return false; } return true; } /** * Remove the VJob from the queue folder. * * @param v the vjob to remove * @return true if the vjob was deleted */ @Override public boolean remove(VJob v) { File f = new File(buildPath(v.id())); return f.exists() && f.delete(); } @Override public VJob get(String id) { File f = new File(buildPath(id)); if (!f.exists()) { return null; } try { return this.builder.build(removeExtension(f), f); } catch (IOException e) { getLogger().debug("Ignoring vJob in " + f.getName() + ": " + e.getMessage()); return null; } catch (VJobBuilderException e) { getLogger().debug("Ignoring vJob in " + f.getName() + ": " + e.getMessage()); return null; } } /** * Build the absolute path of the vjob. * * @param id the identifier of the vjob * @return the absolute path */ private String buildPath(String id) { StringBuilder b = new StringBuilder(); b.append(getFolder().getAbsolutePath()); b.append(File.separator); b.append(id); b.append(EXTENSION); return b.toString(); } /** * Remove the extension of a file name * * @param f the file * @return the name */ private String removeExtension(File f) { String name = f.getName(); return name.substring(0, name.indexOf(EXTENSION)); } /** * Get the directory used to store the vjobs description. * * @return an existing folder */ public File getFolder() { return this.rootDir; } }