package thaw.core; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.Vector; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import thaw.fcp.FCPClientGet; import thaw.fcp.FCPClientPut; import thaw.fcp.FCPQueueManager; import thaw.fcp.FCPTransferQuery; /** * Used when Thaw start and stop: Save the query not running (-> waiting in the Thaw queue) */ public class QueueKeeper { private final static int MIN_PRIORITY = 6; /** * Used to be able to call Logger functions. */ private QueueKeeper() { } private static void loadQuery(final FCPQueueManager queueManager, final Element queryEl, final boolean runningQueue) { FCPTransferQuery newQuery = null; final HashMap params = new HashMap(); final NodeList paramList = queryEl.getElementsByTagName("param"); for(int i = 0;i < paramList.getLength(); i++) { final Node param = paramList.item(i); if((param != null) && (param.getNodeType() == Node.ELEMENT_NODE)) { final Element paramEl = (Element)param; params.put(paramEl.getAttribute("name"), paramEl.getAttribute("value")); } } if((queryEl.getAttribute("type") == null) || "1".equals( queryEl.getAttribute("type") )) { newQuery = new FCPClientGet(queueManager, params); } else { newQuery = new FCPClientPut(queueManager, params); } if(runningQueue) queueManager.addQueryToTheRunningQueue(newQuery, false); else queueManager.addQueryToThePendingQueue(newQuery); } private static void loadQueries(final FCPQueueManager queueManager, final Element queriesEl, final boolean runningQueue) { final NodeList queries = queriesEl.getElementsByTagName("query"); for(int i = 0;i < queries.getLength(); i++) { final Node queryNode = queries.item(i); if((queryNode != null) && (queryNode.getNodeType() == Node.ELEMENT_NODE)) { QueueKeeper.loadQuery(queueManager, (Element)queryNode, runningQueue); } } } public static boolean loadQueue(final FCPQueueManager queueManager, final String fileName) { final File file = new File(fileName); if(!file.exists() || !file.canRead()) { Logger.info(new QueueKeeper(), "Unable to find previous queue state file '"+file.getPath()+"' => Not reloaded from file."); return false; } Document xmlDoc = null; DocumentBuilderFactory xmlFactory = null; DocumentBuilder xmlBuilder = null; Element rootEl = null; xmlFactory = DocumentBuilderFactory.newInstance(); try { xmlBuilder = xmlFactory.newDocumentBuilder(); } catch(final javax.xml.parsers.ParserConfigurationException e) { Logger.warning(new QueueKeeper(), "Unable to load queue because: "+e.toString()); return false; } try { xmlDoc = xmlBuilder.parse(file); } catch(final org.xml.sax.SAXException e) { Logger.warning(new QueueKeeper(), "Unable to load queue because: "+e.toString()); return false; } catch(final java.io.IOException e) { Logger.warning(new QueueKeeper(), "Unable to load queue because: "+e.toString()); return false; } rootEl = xmlDoc.getDocumentElement(); final NodeList runningQueues = rootEl.getElementsByTagName("runningQueue"); for(int i = 0;i < runningQueues.getLength(); i++) { final Node runningQueueNode = runningQueues.item(i); if((runningQueueNode != null) && (runningQueueNode.getNodeType() == Node.ELEMENT_NODE)) { QueueKeeper.loadQueries(queueManager, (Element)runningQueueNode, true); } } final NodeList pendingQueues = rootEl.getElementsByTagName("pendingQueue"); for(int i = 0;i < pendingQueues.getLength(); i++) { final Node pendingQueueNode = pendingQueues.item(i); if((pendingQueueNode != null) && (pendingQueueNode.getNodeType() == Node.ELEMENT_NODE)) { QueueKeeper.loadQueries(queueManager, (Element)pendingQueueNode, false); } } return true; } private static Element saveQuery(final FCPTransferQuery query, final Document xmlDoc) { if(!query.isPersistent()) return null; if(query.isPersistent() && (query.isRunning() || query.isFinished())) return null; final HashMap params = query.getParameters(); final Element queryEl = xmlDoc.createElement("query"); queryEl.setAttribute("type", Integer.toString(query.getQueryType())); for(final Iterator keys = params.keySet().iterator(); keys.hasNext();) { final String key = (String)keys.next(); final Element paramEl = xmlDoc.createElement("param"); paramEl.setAttribute("name", key); paramEl.setAttribute("value", ((String)params.get(key)) ); queryEl.appendChild(paramEl); } return queryEl; } public static boolean saveQueue(final FCPQueueManager queueManager, final String fileName) { final Vector[] pendingQueues = queueManager.getPendingQueues(); synchronized(pendingQueues) { boolean needed = false; for(int i = 0 ; i < pendingQueues.length ; i++) { if(pendingQueues[i].size() > 0) { needed = true; break; } } if(!needed) { Logger.info(new QueueKeeper(), "Nothing in the pending queue to save."); final File file = new File(fileName); file.delete(); // Else we may reload something that we shouldn't when restarting return true; } final File file = new File(fileName); StreamResult fileOut; try { if( (!file.exists() && !file.createNewFile()) || !file.canWrite()) { Logger.warning(new QueueKeeper(), "Unable to write config file '"+file.getPath()+"' (can't write)"); return false; } } catch(final java.io.IOException e) { Logger.warning(new QueueKeeper(), "Error while checking perms to save config: "+e); } fileOut = new StreamResult(file); Document xmlDoc = null; DocumentBuilderFactory xmlFactory = null; DocumentBuilder xmlBuilder = null; DOMImplementation impl = null; Element rootEl = null; xmlFactory = DocumentBuilderFactory.newInstance(); try { xmlBuilder = xmlFactory.newDocumentBuilder(); } catch(final javax.xml.parsers.ParserConfigurationException e) { Logger.error(new QueueKeeper(), "Unable to save queue because: "+e.toString()); return false; } impl = xmlBuilder.getDOMImplementation(); xmlDoc = impl.createDocument(null, "queue", null); rootEl = xmlDoc.getDocumentElement(); final Element pendingQueueEl = xmlDoc.createElement("pendingQueue"); for(int i = 0 ; i <= QueueKeeper.MIN_PRIORITY ; i++) { for(final Iterator runIt = pendingQueues[i].iterator() ; runIt.hasNext(); ) { final FCPTransferQuery query = (FCPTransferQuery)runIt.next(); final Element toSave = QueueKeeper.saveQuery(query, xmlDoc); if(toSave != null) pendingQueueEl.appendChild(toSave); } } rootEl.appendChild(pendingQueueEl); /* Serialization */ final DOMSource domSource = new DOMSource(xmlDoc); final TransformerFactory transformFactory = TransformerFactory.newInstance(); Transformer serializer; try { serializer = transformFactory.newTransformer(); } catch(final javax.xml.transform.TransformerConfigurationException e) { Logger.error(new QueueKeeper(), "Unable to save queue because: "+e.toString()); return false; } serializer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1"); serializer.setOutputProperty(OutputKeys.INDENT,"yes"); /* final step */ try { serializer.transform(domSource, fileOut); } catch(final javax.xml.transform.TransformerException e) { Logger.error(new QueueKeeper(), "Unable to save queue because: "+e.toString()); return false; } } return true; } }