package org.arong.egdownloader.db.impl; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.arong.egdownloader.db.DbTemplate; import org.arong.egdownloader.model.Task; import org.arong.egdownloader.model.TaskList; import org.arong.egdownloader.model.TaskStatus; import org.arong.egdownloader.ui.ComponentConst; import org.arong.util.Dom4jUtil; import org.arong.util.FileUtil; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; /** * 下载任务存取的dom4j实现 * @author 阿荣 * @since 2014-05-29 */ public class TaskDom4jDbTemplate implements DbTemplate<Task> { /** * <?xml version="1.0" encoding="UTF-8"?> * <tasks> * <task id="" url="" name="" saveDir="" createTime="" completedTime="" total="" current="" size="" status=""/> * </tasks> */ private static boolean locked; private static Document dom; static{ updateDom(); } public static void updateDom(){ try { dom = Dom4jUtil.getDOM(ComponentConst.TASK_XML_DATA_PATH); } catch (DocumentException e) { FileUtil.ifNotExistsThenCreate(ComponentConst.DATA_PATH); String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><tasks></tasks>"; int length = 0; //每一次读取的长度 char[] buffer = new char[2048]; //设缓冲最大值为2048字符 //字符串转为字符流 BufferedReader br = null; BufferedWriter bw = null; try { br = new BufferedReader(new StringReader(xml)); bw = new BufferedWriter(new FileWriter(ComponentConst.TASK_XML_DATA_PATH)); while((length = br.read(buffer)) != -1){ //若读到的不是末尾 bw.write(buffer, 0, length); } bw.flush(); dom = Dom4jUtil.getDOM(ComponentConst.TASK_XML_DATA_PATH); } catch (IOException e1) { e1.printStackTrace(); } catch (Exception e1) { e1.printStackTrace(); } finally { if(bw != null){ try { bw.close(); } catch (IOException e1) { e1.printStackTrace(); } } if(br != null){ try { br.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } public boolean store(Task t) { if(t == null){ return false; } while(locked){ store(t); } locked = true; Element ele = task2Element(t); Dom4jUtil.appendElement(dom.getRootElement(), ele); try { Dom4jUtil.writeDOM2XML(ComponentConst.TASK_XML_DATA_PATH, dom); locked = false; } catch (Exception e) { locked = false; return false; } return true; } public boolean store(List<Task> tasks) { if(tasks == null || tasks.size() == 0){ return false; } while(locked){ store(tasks); } locked = true; for (Task t : tasks) { Element ele = task2Element(t); Dom4jUtil.appendElement(dom.getRootElement(), ele); } try { Dom4jUtil.writeDOM2XML(ComponentConst.TASK_XML_DATA_PATH, dom); locked = false; } catch (Exception e) { locked = false; return false; } return true; } public boolean update(Task t) { if(t == null){ return false; } while(locked){ update(t); } locked = true; Node node = dom.selectSingleNode("/tasks/task[@id='" + t.getId() + "']"); if(node != null){ try { Dom4jUtil.deleteElement(dom.getRootElement(), (Element)node); Dom4jUtil.appendElement(dom.getRootElement(), task2Element(t)); Dom4jUtil.writeDOM2XML(ComponentConst.TASK_XML_DATA_PATH, dom); locked = false; return true; } catch (Exception e) { locked = false; return false; } } locked = false; return false; } public boolean update(List<Task> tasks) { if(tasks == null || tasks.size() == 0){ return false; } while(locked){ update(tasks); } locked = true; Node node = null; boolean update = false; for (Task t : tasks) { node = dom.selectSingleNode("/tasks/task[@id='" + t.getId() + "']"); if(node != null){ Dom4jUtil.deleteElement(dom.getRootElement(), (Element)node); Dom4jUtil.appendElement(dom.getRootElement(), task2Element(t)); update = true; } } if(update){ try { Dom4jUtil.writeDOM2XML(ComponentConst.TASK_XML_DATA_PATH, dom); locked = false; return true; } catch (Exception e) { locked = false; return false; } } locked = false; return false; } public boolean delete(Task t) { while(locked){ delete(t); } locked = true; Node node = dom.selectSingleNode("/tasks/task[@id='" + t.getId() + "']"); if(node != null){ try { Dom4jUtil.deleteElement(dom.getRootElement(), (Element)node); Dom4jUtil.writeDOM2XML(ComponentConst.TASK_XML_DATA_PATH, dom); locked = false; return true; } catch (Exception e) { locked = false; return false; } } locked = false; return false; } public boolean delete(List<Task> tasks) { if(tasks == null || tasks.size() == 0){ return false; } while(locked){ delete(tasks); } locked = true; Node node = null; boolean delete = false; for (Task t : tasks) { node = dom.selectSingleNode("/tasks/task[@id='" + t.getId() + "']"); if(node != null){ Dom4jUtil.deleteElement(dom.getRootElement(), (Element)node); delete = true; } } if(delete){ try { Dom4jUtil.writeDOM2XML(ComponentConst.TASK_XML_DATA_PATH, dom); locked = false; return true; } catch (Exception e) { locked = false; return false; } } locked = false; return false; } public List<Task> query() { @SuppressWarnings("unchecked") List<Node> nodes = dom.selectNodes("/tasks/task"); if(nodes != null && nodes.size() > 0){ TaskList<Task> tasks = new TaskList<Task>(); for (Node node : nodes) { tasks.add(node2Task(node)); } //按照创建日期进行降序排序 Collections.sort(tasks, new Comparator<Task>() { private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public int compare(Task o1, Task o2) { try { if(sdf.parse(o1.getCreateTime()).after(sdf.parse(o2.getCreateTime()))){ return -1; }else{ return 1; } } catch (ParseException e) { return 0; } } }); return tasks; } return null; } public List<Task> query(Object id) { @SuppressWarnings("unchecked") List<Node> nodes = dom.selectNodes("/tasks/task[@id='" + id.toString() + "']"); if(nodes != null && nodes.size() > 0){ List<Task> tasks = new ArrayList<Task>(); for (Node node : nodes) { tasks.add(node2Task(node)); } return tasks; } return null; } public List<Task> query(String name, String value) { @SuppressWarnings("unchecked") List<Node> nodes = dom.selectNodes("/tasks/task[@" + name + "='" + value + "']"); List<Task> tasks = null; if(nodes != null && nodes.size() > 0){ tasks = new ArrayList<Task>(); for (Node node : nodes) { tasks.add(node2Task(node)); } } return tasks; } public Task get(Object id) { Node node = dom.selectSingleNode("/tasks/task[@id='" + id.toString() + "']"); if(node != null){ return node2Task(node); } return null; } public boolean exsits(String name, String value) { Node node = dom.selectSingleNode("/tasks/task[@" + name + "='" + value + "']"); if(node != null){ return true; } return false; } private static Element task2Element(Task t){ Element ele = DocumentHelper.createElement("task"); ele.addAttribute("id", t.getId()); ele.addAttribute("url", t.getUrl()); ele.addAttribute("name", t.getName()); ele.addAttribute("subname", t.getSubname()); ele.addAttribute("coverUrl", t.getCoverUrl()); ele.addAttribute("language", t.getLanguage()); ele.addAttribute("type", t.getType()); ele.addAttribute("saveDir", t.getSaveDir()); ele.addAttribute("tag", t.getTag()); ele.addAttribute("readed", t.isReaded() + ""); ele.addAttribute("createTime", t.getCreateTime()); ele.addAttribute("completedTime", t.getCompletedTime()); ele.addAttribute("total", t.getTotal() + ""); ele.addAttribute("current", t.getCurrent() + ""); ele.addAttribute("size", t.getSize()); ele.addAttribute("status", t.getStatus().getStatus() + ""); ele.addAttribute("start", t.getStart() + ""); ele.addAttribute("end", t.getEnd() + ""); return ele; } private static Task node2Task(Node node){ Element ele = (Element)node; Task task = new Task(); task.setId(ele.attributeValue("id")); task.setUrl(ele.attributeValue("url")); task.setName(ele.attributeValue("name")); task.setSubname(ele.attributeValue("subname") == null ? "" : ele.attributeValue("subname")); task.setCoverUrl(ele.attributeValue("coverUrl")); task.setLanguage(ele.attributeValue("language") == null ? "" : ele.attributeValue("language")); task.setType(ele.attributeValue("type") == null ? "" : ele.attributeValue("type")); task.setSaveDir(ele.attributeValue("saveDir")); task.setTag(ele.attributeValue("tag") == null ? "一般" : ele.attributeValue("tag")); task.setReaded("true".equals(ele.attributeValue("readed")) ? true : false); task.setCreateTime(ele.attributeValue("createTime")); task.setCompletedTime(ele.attributeValue("completedTime")); task.setTotal(ele.attributeValue("total") == null ? 0 : Integer.parseInt(ele.attributeValue("total"))); task.setCurrent(ele.attributeValue("current") == null ? 0 : Integer.parseInt(ele.attributeValue("current"))); task.setSize(ele.attributeValue("size") == null ? "" : ele.attributeValue("size")); //如果任务为下载中,则加载到内存中设置为已暂停,由用户手动开启任务 TaskStatus ts = TaskStatus.parseTaskStatus(ele.attributeValue("status")); if(ts == TaskStatus.STARTED){ ts = TaskStatus.STOPED; } task.setStatus(ts); task.setStart(ele.attributeValue("start") == null ? 1 : Integer.parseInt(ele.attributeValue("start"))); task.setEnd(ele.attributeValue("end") == null ? task.getTotal() : Integer.parseInt(ele.attributeValue("end"))); return task; } }