Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.shaman.rpg.editor.project.elements; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.util.logging.Logger; import org.jdom2.Document; import org.jdom2.JDOMException; import org.jdom2.Namespace; import org.jdom2.input.SAXBuilder; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; import org.openide.filesystems.FileAlreadyLockedException; import org.openide.filesystems.FileObject; import org.openide.util.Exceptions; /** * Helper class for loading and saving {@link JdomGroup} and {@link JdomElement}. * @author Sebastian Wei */ public class JdomElements { private static final String FILENAME = ".elements"; private static final String ROOT_NAME = "elements"; private static final String ROOT_NAMESPACE = "game"; private static final int AUTOSAVE_PERIOD = 1000; //wait 1 sec private static final Logger LOG = Logger.getLogger(Elements.class.getName()); static final String ATTRIBUTE_ID = "id"; static final Namespace NAMESPACE = Namespace.getNamespace(ROOT_NAMESPACE); volatile boolean hasChanges = false; private FileObject file; private Document doc; private JdomGroup root; private boolean autosave; private AutosaveThread autosaveThread; static void setAttributeNullCheck(org.jdom2.Element element, String attribute, String value) { if (value != null) { element.setAttribute(attribute, value); } } /** * <b>Do not use, an instance is provided in the project's lookup</b>. * @param projectRoot */ public JdomElements(FileObject projectRoot) { try { file = projectRoot.getFileObject(FILENAME); if (file == null) { file = projectRoot.createData(FILENAME); //set hidden flag //setHidden(FileUtil.toFile(file).toPath()); root = newDoc(); save(); } else { //load SAXBuilder b = new SAXBuilder(); try (InputStream in = file.getInputStream()) { doc = b.build(in); } catch (JDOMException ex) { Exceptions.printStackTrace(ex); //create new file root = newDoc(); save(); return; } //validate file org.jdom2.Element e = doc.getRootElement(); if (!e.getName().equals(ROOT_NAME) || !e.getNamespaceURI().equals(ROOT_NAMESPACE)) { //invalid root file -> corrupt file -> create new file LOG.warning("corrupt elements file: invalid root node"); root = newDoc(); save(); return; } //create root group root = new JdomGroup(null, this, e, 0); root.load(); } } catch (IOException e) { Exceptions.printStackTrace(e); } } @Deprecated private void setHidden(Path path) { try { Boolean hidden = (Boolean) Files.getAttribute(path, "dos:hidden", LinkOption.NOFOLLOW_LINKS); if (hidden != null && !hidden) { Files.setAttribute(path, "dos:hidden", Boolean.TRUE, LinkOption.NOFOLLOW_LINKS); } } catch (IOException ex) { Exceptions.printStackTrace(ex); } } private JdomGroup newDoc() { //create new file org.jdom2.Element e = new org.jdom2.Element(ROOT_NAME); e.setNamespace(NAMESPACE); //e.setAttribute("xmlns", ROOT_NAMESPACE); doc = new Document(e); JdomGroup r = new JdomGroup(null, this, e, 0); return r; } public JdomGroup getRoot() { return root; } public synchronized void save() { root.update(); XMLOutputter out = new XMLOutputter(Format.getPrettyFormat()); try (OutputStream stream = file.getOutputStream()) { out.output(doc, stream); } catch (FileAlreadyLockedException ex) { Exceptions.printStackTrace(ex); return; } catch (IOException ex) { Exceptions.printStackTrace(ex); return; } //debug LOG.fine("elements saved"); // try { // for (String line : file.asLines()) { // System.out.println(line); // } // } catch (IOException ex) { // Exceptions.printStackTrace(ex); // } } public synchronized void setAutosave(boolean autosave) { if (this.autosave == autosave) { return; //no changes } this.autosave = autosave; if (autosave) { //start autosave thread autosaveThread = new AutosaveThread(); autosaveThread.start(); } else { //stop autosave thread if (autosaveThread != null) { autosaveThread.interrupt(); autosaveThread = null; } } } public boolean isAutosave() { return autosave; } private class AutosaveThread extends Thread { @Override public void run() { while (true) { if (Thread.interrupted()) { break; //autosave turned off } if (hasChanges) { hasChanges = false; save(); } if (Thread.interrupted()) { break; //autosave turned off } try { Thread.sleep(AUTOSAVE_PERIOD); } catch (InterruptedException ex) { break; //autosave turned off } } LOG.info("autosave thread turned off"); } } }