diff --git a/apisupport.project/src/org/netbeans/modules/apisupport/project/api/LayerHandle.java b/apisupport.project/src/org/netbeans/modules/apisupport/project/api/LayerHandle.java
--- a/apisupport.project/src/org/netbeans/modules/apisupport/project/api/LayerHandle.java
+++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/api/LayerHandle.java
@@ -42,8 +42,6 @@
package org.netbeans.modules.apisupport.project.api;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -59,7 +57,6 @@
import org.netbeans.modules.apisupport.project.NbModuleProjectGenerator;
import org.netbeans.modules.apisupport.project.Util;
import org.netbeans.modules.apisupport.project.layers.LayerUtils;
-import org.netbeans.modules.apisupport.project.layers.LayerUtils.SavableTreeEditorCookie;
import org.netbeans.modules.apisupport.project.layers.WritableXMLFileSystem;
import org.netbeans.modules.apisupport.project.spi.NbModuleProvider;
import org.openide.ErrorManager;
@@ -68,7 +65,6 @@
import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileRenameEvent;
-import org.openide.filesystems.FileStateInvalidException;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.MultiFileSystem;
@@ -99,7 +95,7 @@
private final Project project;
private final FileObject layerXML;
private FileSystem fs;
- private SavableTreeEditorCookie cookie;
+ private WritableXMLFileSystem wxmlfs;
private boolean autosave;
public LayerHandle(Project project, FileObject layerXML) {
@@ -120,11 +116,11 @@
public synchronized FileSystem layer(boolean create) {
if (fs == null) {
FileObject xml = getLayerFile();
- if (xml == null) {
- if (!create) {
- return new DualLayers(null);
- }
- try {
+ try {
+ if (xml == null) {
+ if (!create) {
+ return new DualLayers(null);
+ }
NbModuleProvider module = project.getLookup().lookup(NbModuleProvider.class);
FileObject manifest = module.getManifestFile();
if (manifest != null) { // #121056
@@ -138,29 +134,35 @@
}
}
xml = NbModuleProjectGenerator.createLayer(project.getProjectDirectory(), module.getResourceDirectoryPath(false) + '/' + newLayerPath());
- } catch (IOException e) {
- Util.err.notify(ErrorManager.INFORMATIONAL, e);
- return fs = FileUtil.createMemoryFileSystem();
}
+ WritableXMLFileSystem _wxmlfs = new WritableXMLFileSystem(xml, LayerUtils.findResourceCP(project));
+ fs = new DualLayers(_wxmlfs);
+ wxmlfs = _wxmlfs;
+ // XXX maybe cleaner & more reliable to listen to EditorCookie.Observable.PROP_MODIFIED
+ wxmlfs.addFileChangeListener(new FileChangeListener() {
+ public @Override void fileFolderCreated(FileEvent fe) {
+ setAutosave(autosave); // causes it to save if autosave is on
+ }
+ public @Override void fileDataCreated(FileEvent fe) {
+ setAutosave(autosave);
+ }
+ public @Override void fileChanged(FileEvent fe) {
+ setAutosave(autosave);
+ }
+ public @Override void fileDeleted(FileEvent fe) {
+ setAutosave(autosave);
+ }
+ public @Override void fileRenamed(FileRenameEvent fe) {
+ setAutosave(autosave);
+ }
+ public @Override void fileAttributeChanged(FileAttributeEvent fe) {
+ setAutosave(autosave);
+ }
+ });
+ } catch (IOException e) {
+ Util.err.notify(ErrorManager.INFORMATIONAL, e);
+ fs = FileUtil.createMemoryFileSystem();
}
- try {
- fs = new DualLayers(new WritableXMLFileSystem(xml.getURL(), cookie = LayerUtils.cookieForFile(xml), LayerUtils.findResourceCP(project)));
- } catch (FileStateInvalidException e) {
- throw new AssertionError(e);
- }
- cookie.addPropertyChangeListener(new PropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent evt) {
- //System.err.println("changed in mem");
- if (autosave && SavableTreeEditorCookie.PROP_DIRTY.equals(evt.getPropertyName())) {
- //System.err.println(" will save...");
- try {
- save();
- } catch (IOException e) {
- Util.err.notify(ErrorManager.INFORMATIONAL, e);
- }
- }
- }
- });
}
return fs;
}
@@ -215,10 +217,10 @@
* Note that nonempty layer entries you created will already be on disk.
*/
public void save() throws IOException {
- if (cookie == null) {
+ if (wxmlfs == null) {
throw new IOException("Cannot save a nonexistent layer"); // NOI18N
}
- cookie.save();
+ wxmlfs.save();
}
/**
@@ -251,9 +253,9 @@
*/
public void setAutosave(boolean autosave) {
this.autosave = autosave;
- if (autosave && cookie != null) {
+ if (autosave && wxmlfs != null) {
try {
- cookie.save();
+ save();
} catch (IOException e) {
Util.err.notify(ErrorManager.INFORMATIONAL, e);
}
diff --git a/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/LayerUtils.java b/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/LayerUtils.java
--- a/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/LayerUtils.java
+++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/LayerUtils.java
@@ -44,14 +44,10 @@
package org.netbeans.modules.apisupport.project.layers;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
-import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@@ -85,26 +81,13 @@
import org.netbeans.modules.apisupport.project.universe.ModuleEntry;
import org.netbeans.modules.apisupport.project.universe.ModuleList;
import org.netbeans.modules.apisupport.project.universe.NbPlatform;
-import org.netbeans.modules.xml.tax.cookies.TreeEditorCookie;
-import org.netbeans.modules.xml.tax.parser.XMLParsingSupport;
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
-import org.netbeans.tax.TreeDocumentRoot;
-import org.netbeans.tax.TreeException;
-import org.netbeans.tax.TreeObject;
-import org.netbeans.tax.io.TreeStreamResult;
import org.openide.ErrorManager;
-import org.openide.filesystems.FileAttributeEvent;
-import org.openide.filesystems.FileChangeListener;
-import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
-import org.openide.filesystems.FileRenameEvent;
import org.openide.filesystems.FileStateInvalidException;
import org.openide.filesystems.FileSystem;
-import org.openide.filesystems.FileSystem.AtomicAction;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.XMLFileSystem;
-import org.openide.util.Task;
-import org.xml.sax.InputSource;
/**
* Misc support for dealing with layers.
@@ -296,151 +279,6 @@
}
/**
- * Representation of in-memory TAX tree which can be saved upon request.
- */
- public interface SavableTreeEditorCookie extends TreeEditorCookie {
-
- /** property change fired when dirty flag changes */
- String PROP_DIRTY = "dirty"; // NOI18N
-
- /** true if there are in-memory mods */
- boolean isDirty();
-
- /** try to save any in-memory mods to disk */
- void save() throws IOException;
-
- }
-
- private static final class CookieImpl implements SavableTreeEditorCookie, FileChangeListener, AtomicAction {
- private TreeDocumentRoot root;
- private boolean dirty;
- private Exception problem;
- private final FileObject f;
- private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
- public CookieImpl(FileObject f) {
- //System.err.println("new CookieImpl for " + f);
- this.f = f;
- f.addFileChangeListener(FileUtil.weakFileChangeListener(this, f));
- }
- public TreeDocumentRoot getDocumentRoot() {
- return root;
- }
- public int getStatus() {
- if (problem != null) {
- return TreeEditorCookie.STATUS_ERROR;
- } else if (root != null) {
- return TreeEditorCookie.STATUS_OK;
- } else {
- return TreeEditorCookie.STATUS_NOT;
- }
- }
- public TreeDocumentRoot openDocumentRoot() throws IOException, TreeException {
- if (root == null && f.isValid()) {
- try {
- //System.err.println("openDocumentRoot: really opening");
- boolean oldDirty = dirty;
- int oldStatus = getStatus();
- root = new XMLParsingSupport().parse(new InputSource(f.getURL().toExternalForm()));
- problem = null;
- dirty = false;
- pcs.firePropertyChange(PROP_DIRTY, oldDirty, false);
- pcs.firePropertyChange(PROP_STATUS, oldStatus, TreeEditorCookie.STATUS_OK);
- //pcs.firePropertyChange(PROP_DOCUMENT_ROOT, null, root);
- } catch (IOException e) {
- problem = e;
- throw e;
- } catch (TreeException e) {
- problem = e;
- throw e;
- }
- ((TreeObject) root).addPropertyChangeListener(new PropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent evt) {
- //System.err.println("tree modified");
- modified();
- }
- });
- }
- return root;
- }
- public Task prepareDocumentRoot() {
- throw new UnsupportedOperationException();
- }
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
- private void modified() {
- //System.err.println("modified(): dirty=" + dirty + " in " + Thread.currentThread().getName() + " for " + this);
- if (!dirty) {
- dirty = true;
- pcs.firePropertyChange(PROP_DIRTY, false, true);
- }
- }
- public boolean isDirty() {
- return dirty;
- }
- public synchronized void save() throws IOException {
- //System.err.println("save(): dirty=" + dirty + " in " + Thread.currentThread().getName() + " for " + this);
- if (root == null || !dirty) {
- return;
- }
- //System.err.println("saving in " + Thread.currentThread().getName() + " for " + this);
- f.getFileSystem().runAtomicAction(this);
- //System.err.println("!saving in " + Thread.currentThread().getName() + " for " + this);
- dirty = false;
- pcs.firePropertyChange(PROP_DIRTY, true, false);
- }
- public void run() throws IOException {
- OutputStream os = f.getOutputStream();
- try {
- new TreeStreamResult(os).getWriter(root).writeDocument();
- } catch (TreeException e) {
- throw (IOException) new IOException(e.toString()).initCause(e);
- } finally {
- os.close();
- }
- }
- public void fileChanged(FileEvent fe) {
- changed(fe);
- }
- public void fileDeleted(FileEvent fe) {
- changed(fe);
- }
- public void fileRenamed(FileRenameEvent fe) {
- changed(fe);
- }
- public void fileAttributeChanged(FileAttributeEvent fe) {
- // ignore
- }
- public void fileFolderCreated(FileEvent fe) {
- assert false;
- }
- public void fileDataCreated(FileEvent fe) {
- assert false;
- }
- private void changed(FileEvent fe) {
- //System.err.println("changed on disk in " + Thread.currentThread().getName() + " for " + this);
- //Thread.dumpStack();
- synchronized (this) {
- if (fe.firedFrom(this)) {
- //System.err.println("(my own change)");
- return;
- }
- problem = null;
- dirty = false;
- root = null;
- }
- pcs.firePropertyChange(PROP_DOCUMENT_ROOT, null, null);
- }
- }
-
- public static SavableTreeEditorCookie cookieForFile(FileObject f) {
- return new CookieImpl(f);
- }
-
- /**
* Get a filesystem that will look like what this project would "see".
* There are four possibilities:
*
diff --git a/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystem.java b/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystem.java
--- a/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystem.java
+++ b/apisupport.project/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystem.java
@@ -65,24 +65,12 @@
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.Set;
import org.netbeans.api.java.classpath.ClassPath;
-import org.netbeans.modules.apisupport.project.Util;
-import org.netbeans.modules.xml.tax.cookies.TreeEditorCookie;
-import org.netbeans.tax.InvalidArgumentException;
-import org.netbeans.tax.ReadOnlyException;
-import org.netbeans.tax.TreeAttribute;
-import org.netbeans.tax.TreeCDATASection;
-import org.netbeans.tax.TreeChild;
-import org.netbeans.tax.TreeDocumentRoot;
-import org.netbeans.tax.TreeDocumentType;
-import org.netbeans.tax.TreeElement;
-import org.netbeans.tax.TreeException;
-import org.netbeans.tax.TreeObjectList;
-import org.netbeans.tax.TreeParentNode;
-import org.netbeans.tax.TreeText;
-import org.openide.ErrorManager;
+import org.netbeans.editor.BaseDocument;
+import org.netbeans.modules.xml.xam.ModelSource;
+import org.netbeans.modules.xml.xdm.XDMModel;
+import org.openide.cookies.EditorCookie;
import org.openide.filesystems.AbstractFileSystem;
import org.openide.filesystems.FileAttributeEvent;
import org.openide.filesystems.FileChangeListener;
@@ -91,19 +79,24 @@
import org.openide.filesystems.FileRenameEvent;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
+import org.openide.loaders.DataObject;
import org.openide.util.Enumerations;
-import org.openide.util.WeakListeners;
+import org.openide.util.lookup.Lookups;
+import org.openide.xml.XMLUtil;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
/**
- * A filesystem which is based on a TAX document and implements
+ * A filesystem which is based on an XML document and implements
* the same syntax as XMLFileSystem, from which inspiration is taken.
* Not implemented similarly to XMLFileSystem because this is writable
* and designed specifically to write human-readable XML and work nicely
* as an authoring tool. The filesystem expects to get an XML document
- * according to DTD "-//NetBeans//DTD Filesystem 1.0//EN" (or 1.1 is OK).
- * When it is changed via FileSystems API, it will fire TAX
- * events. Not intended to be efficient or terribly robust, since it
- * is development-time only.
+ * according to DTD "-//NetBeans//DTD Filesystem 1.0//EN" (or 1.1 or 1.2 is OK).
+ * When it is changed via the FileSystems API, it will update the document.
+ * Not intended to be efficient or terribly robust, since it is development-time only.
* @author Jesse Glick
*/
public final class WritableXMLFileSystem extends AbstractFileSystem
@@ -111,37 +104,43 @@
AbstractFileSystem.Change,
AbstractFileSystem.Info,
AbstractFileSystem.List,
- //AbstractFileSystem.Transfer,
FileChangeListener,
PropertyChangeListener {
- private final TreeEditorCookie cookie;
- private TreeDocumentRoot doc; // may be null if malformed
+ private final EditorCookie editorCookie;
+ private final XDMModel model;
private URL location;
- private String suffix; // for branding/localization like "_f4j_ce_ja"; never null, at worst ""
private final FileChangeListener fileChangeListener;
private ClassPath classpath; // OK to be null
- public WritableXMLFileSystem(URL location, TreeEditorCookie cookie, ClassPath classpath) {
- this.attr = this;
- this.change = this;
- this.info = this;
- this.list = this;
- //this.transfer = this;
- this.cookie = cookie;
- suffix = "";
- try {
- doc = cookie.openDocumentRoot();
- } catch (TreeException e) {
- Util.err.notify(ErrorManager.INFORMATIONAL, e);
- } catch (IOException e) {
- Util.err.notify(ErrorManager.INFORMATIONAL, e);
+ @SuppressWarnings("LeakingThisInConstructor")
+ public WritableXMLFileSystem(FileObject xml, ClassPath classpath) throws IOException {
+ editorCookie = DataObject.find(xml).getLookup().lookup(EditorCookie.class);
+ if (editorCookie == null) {
+ throw new IOException("Noneditable layer: " + xml);
}
+ model = new XDMModel(new ModelSource(Lookups.fixed(xml, (BaseDocument) editorCookie.openDocument()), true));
+ model.sync();
+ model.addPropertyChangeListener(this);
+ model.setPretty(true);
+ model.setIndentation(" "); // NOI18N
+ attr = this;
+ change = this;
+ info = this;
+ list = this;
fileChangeListener = FileUtil.weakFileChangeListener(this, null);
- cookie.addPropertyChangeListener(WeakListeners.propertyChange(this, cookie));
- setLocation(location);
+ setLocation(xml.getURL());
setClasspath(classpath);
}
+
+ /**
+ * Saves any outstanding modifications to disk.
+ * (Modifications are always applied immediately to an editor document.)
+ * @throws IOException if the document could not be saved
+ */
+ public void save() throws IOException {
+ editorCookie.saveDocument();
+ }
private void writeObject(ObjectOutputStream out) throws IOException {
throw new NotSerializableException("WritableXMLFileSystem is not persistent"); // NOI18N
@@ -159,7 +158,7 @@
this.classpath = classpath;
}
- public String getDisplayName() {
+ public @Override String getDisplayName() {
FileObject fo = URLMapper.findFileObject(location);
if (fo != null) {
return FileUtil.getFileDisplayName(fo);
@@ -168,35 +167,26 @@
}
}
- public boolean isReadOnly() {
+ public @Override boolean isReadOnly() {
return false;
}
- private TreeElement getRootElement() {
- if (doc == null) {
- return null;
- }
- Iterator it;
- it = doc.getChildNodes().iterator();
- while (it.hasNext()) {
- Object next = it.next();
- if (next instanceof TreeElement) {
- return (TreeElement) next;
- }
- }
- return null;
+ private Element getRootElement() {
+ return model.getDocument().getDocumentElement();
}
/** Given a resource name, find the matching DOM element.
* @return a or or element, or null if file does not exist
*/
- private TreeElement findElement(String name) {
+ private Element findElement(String name) {
return findElementIn(getRootElement(), name);
}
/** helper method only */
- private static TreeElement findElementIn(TreeElement el, String name) {
- if (el == null) return null;
- if (name.equals("")) { // NOI18N
+ private static Element findElementIn(Element el, String name) {
+ if (el == null) {
+ return null;
+ }
+ if (name.isEmpty()) {
return el;
} else {
int idx = name.indexOf('/');
@@ -208,14 +198,12 @@
nextName = name.substring(0, idx);
remainder = name.substring(idx + 1);
}
- TreeElement subel = null;
- Iterator it = el.getChildNodes(TreeElement.class).iterator();
- while (it.hasNext()) {
- TreeElement e = (TreeElement) it.next();
- if (e.getLocalName().equals("file") || // NOI18N
- e.getLocalName().equals("folder")) { // NOI18N
- TreeAttribute nameAttr = e.getAttribute("name"); // NOI18N
- if (nameAttr != null && nameAttr.getValue().equals(nextName)) {
+ Element subel = null;
+ for (Element e : XMLUtil.findSubElements(el)) {
+ if (e.getTagName().equals("file") || // NOI18N
+ e.getTagName().equals("folder")) { // NOI18N
+ String nameAttr = e.getAttribute("name"); // NOI18N
+ if (nameAttr.equals(nextName)) {
subel = e;
break;
}
@@ -225,53 +213,34 @@
}
}
- public boolean folder(String name) {
- TreeElement el = findElement(name);
+ public @Override boolean folder(String name) {
+ Element el = findElement(name);
if (el == null) {
//System.err.println("folder <" + name + ">: false, no such element");
return false;
}
- boolean res = el.getLocalName().equals("folder"); // NOI18N
+ boolean res = el.getTagName().equals("folder"); // NOI18N
//System.err.println("folder <" + name + ">: " + res);
return res;
}
- /*
- private static final Set warnedAboutDupeKids = new HashSet(1); // Set
- */
- public String[] children(String f) {
- TreeElement el = findElement(f);
+ public @Override String[] children(String f) {
+ Element el = findElement(f);
if (el == null) {
//System.err.println("children <" + f + ">: none, no such element");
return new String[] {};
}
ArrayList kids = new ArrayList();
Set allNames = new HashSet();
- Iterator it = el.getChildNodes(TreeElement.class).iterator();
- while (it.hasNext()) {
- TreeElement sub = (TreeElement) it.next();
- if (sub.getLocalName().equals("file") || // NOI18N
- sub.getLocalName().equals("folder")) { // NOI18N
- TreeAttribute childName = sub.getAttribute("name"); // NOI18N
- if (childName == null) {
+ for (Element sub : XMLUtil.findSubElements(el)) {
+ if (sub.getTagName().equals("file") || // NOI18N
+ sub.getTagName().equals("folder")) { // NOI18N
+ String name = sub.getAttribute("name"); // NOI18N
+ if (name.isEmpty()) {
continue;
}
- String name = childName.getValue(); // NOI18N
if (allNames.add(name)) {
kids.add(name);
- /*
- } else {
- if (warnedAboutDupeKids.add(location + ":" + f + "/" + name)) { // NOI18N
- // #18699: will deadlock if you try to change anything.
- if (f.equals("")) { // NOI18N
- LayerDataNode.getErr().println("WARNING: in " + xmlfile + " the root folder contains the child " + name + " more than once.");
- } else {
- LayerDataNode.getErr().println("WARNING: in " + xmlfile + " the folder " + f + " contains the child " + name + " more than once.");
- }
- //LayerDataNode.getErr().println("The Open APIs Support module will not work properly with such a layer.");
- //LayerDataNode.getErr().println("Please edit the XML text and merge together all children of a with the same name.");
- }
- */
}
}
}
@@ -281,21 +250,24 @@
/** retrieve byte contents of a named resource */
private byte[] getContentsOf(final String name) throws FileNotFoundException {
- TreeElement el = findElement(name);
- if (el == null) throw new FileNotFoundException(name);
- TreeAttribute urlAttr = el.getAttribute("url"); // NOI18N
- if (urlAttr != null) {
+ Element el = findElement(name);
+ if (el == null) {
+ throw new FileNotFoundException(name);
+ }
+ String sURL = el.getAttribute("url"); // NOI18N
+ if (!sURL.isEmpty()) {
try {
- String sURL = urlAttr.getValue();
URI uri = new URI(null, sURL, null);
boolean nbmRelative = sURL.startsWith("nbres:") || sURL.startsWith("nbresloc:");
URL url = nbmRelative ? uri.toURL() : new URL(location, uri.getRawPath());
- URL[] u = LayerUtils.currentify(url, suffix, classpath);
+ URL[] u = LayerUtils.currentify(url, "", classpath);
URLConnection conn = u[0].openConnection();
conn.connect();
InputStream is = conn.getInputStream();
byte[] buf = new byte[conn.getContentLength()];
- if (is.read(buf) != buf.length) throw new IOException("wrong content length"); // NOI18N
+ if (is.read(buf) != buf.length) {
+ throw new IOException("wrong content length");
+ }
// Also listen to changes in it.
FileObject fo = URLMapper.findFileObject(u[0]);
if (fo != null) {
@@ -309,14 +281,12 @@
throw new FileNotFoundException(use.getMessage());
}
} else {
- StringBuffer buf = new StringBuffer();
- Iterator it = el.getChildNodes().iterator();
- while (it.hasNext()) {
- Object o = it.next();
- if (o instanceof TreeCDATASection) {
- buf.append(((TreeCDATASection) o).getData());
- } else if (o instanceof TreeText) {
- buf.append(((TreeText) o).getData().trim());
+ StringBuilder buf = new StringBuilder();
+ NodeList nl = el.getChildNodes();
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node n = nl.item(i);
+ if (n.getNodeType() == Node.CDATA_SECTION_NODE || n.getNodeType() == Node.TEXT_NODE) {
+ buf.append(((CharacterData) n).getData());
}
}
try {
@@ -331,18 +301,17 @@
// [PENDING] should I/O from/to external text files be done via EditorCookie?
// Not clear if this is safe (call from FS -> DS) even tho in separate FSs...
- public InputStream inputStream(String name) throws FileNotFoundException {
+ public @Override InputStream inputStream(String name) throws FileNotFoundException {
return new ByteArrayInputStream(getContentsOf(name));
}
- public OutputStream outputStream(final String name) throws IOException {
- final TreeElement el = findElement(name);
+ public @Override OutputStream outputStream(final String name) throws IOException {
+ final Element el = findElement(name);
if (el == null) {
throw new FileNotFoundException(name);
}
- TreeAttribute urlAttr = el.getAttribute("url"); // NOI18N
- if (urlAttr != null) {
- String u = urlAttr.getValue();
+ String u = el.getAttribute("url"); // NOI18N
+ if (!u.isEmpty()) {
if (URI.create(u).isAbsolute()) {
// What to do? Can't overwrite it, obviously.
throw new IOException(name);
@@ -356,7 +325,7 @@
}
// We will change the layer file.
return new ByteArrayOutputStream() {
- public void close() throws IOException {
+ public @Override void close() throws IOException {
super.close();
final byte[] contents = toByteArray();
/* If desired to kill any existing inline content:
@@ -380,7 +349,7 @@
final String externalName = LayerUtils.findGeneratedName(parent, name);
assert externalName.indexOf('/') == -1 : externalName;
parent.getFileSystem().runAtomicAction(new AtomicAction() {
- public void run() throws IOException {
+ public @Override void run() throws IOException {
FileObject externalFile = parent.createData(externalName);
OutputStream os = externalFile.getOutputStream();
try {
@@ -391,13 +360,7 @@
externalFile.addFileChangeListener(fileChangeListener);
}
});
- try {
- el.addAttribute("url", externalName); // NOI18N
- } catch (ReadOnlyException e) {
- throw (IOException) new IOException(e.toString()).initCause(e);
- } catch (InvalidArgumentException e) {
- assert false : e;
- }
+ model.setAttribute((org.netbeans.modules.xml.xdm.nodes.Element) el, "url", externalName); // NOI18N
}
};
}
@@ -422,52 +385,44 @@
parentName = name.substring(0, idx);
baseName = name.substring(idx + 1);
}
- TreeElement el = findElement(parentName);
+ Element el = findElement(parentName);
if (el == null) {
throw new FileNotFoundException(parentName);
}
- try {
- TreeElement nue = new TreeElement(folder ? "folder" : "file", true); // NOI18N
- nue.addAttribute("name", baseName); // NOI18N
- appendWithIndent(el, nue);
- } catch (InvalidArgumentException e) {
- assert false : e;
- } catch (ReadOnlyException e) {
- throw (IOException) new IOException(e.toString()).initCause(e);
- }
+ Element nue = el.getOwnerDocument().createElement(folder ? "folder" : "file"); // NOI18N
+ nue.setAttribute("name", baseName); // NOI18N
+ model.insertBefore((org.netbeans.modules.xml.xdm.nodes.Node) el,
+ (org.netbeans.modules.xml.xdm.nodes.Node) nue,
+ (org.netbeans.modules.xml.xdm.nodes.Node) findInsertionPosition(el, nue));
}
- public void createFolder(String name) throws IOException {
+ public @Override void createFolder(String name) throws IOException {
createFileOrFolder(name, true);
}
- public void createData(String name) throws IOException {
+ public @Override void createData(String name) throws IOException {
createFileOrFolder(name, false);
}
- public void delete(String name) throws IOException {
- TreeElement el = findElement(name);
+ public @Override void delete(String name) throws IOException {
+ Element el = findElement(name);
if (el == null) {
throw new FileNotFoundException(name);
}
- TreeAttribute externalName = el.getAttribute("url"); // NOI18N
- if (externalName != null && !URI.create(externalName.getValue()).isAbsolute()) {
+ String externalName = el.getAttribute("url"); // NOI18N
+ if (!externalName.isEmpty() && !URI.create(externalName).isAbsolute()) {
// Delete the external file if it can be found.
- FileObject externalFile = URLMapper.findFileObject(new URL(location, externalName.getValue()));
+ FileObject externalFile = URLMapper.findFileObject(new URL(location, externalName));
if (externalFile != null) {
externalFile.removeFileChangeListener(fileChangeListener);
externalFile.delete();
}
}
- try {
- deleteWithIndent((TreeChild) el);
- } catch (ReadOnlyException e) {
- throw (IOException) new IOException(e.toString()).initCause(e);
- }
+ model.removeChildNodes((org.netbeans.modules.xml.xdm.nodes.Node) el.getParentNode(), Collections.singleton((org.netbeans.modules.xml.xdm.nodes.Node) el));
}
- public void rename(String oldName, String newName) throws IOException {
- TreeElement el = findElement(oldName);
+ public @Override void rename(String oldName, String newName) throws IOException {
+ Element el = findElement(oldName);
if (el == null) {
throw new FileNotFoundException(oldName);
}
@@ -478,108 +433,29 @@
String newBaseName = newName.substring(idx);
assert newBaseName.indexOf('/') == -1;
assert newBaseName.length() > 0;
- try {
- el.getAttribute("name").setValue(newBaseName); // NOI18N
- } catch (ReadOnlyException e) {
- throw (IOException) new IOException(e.toString()).initCause(e);
- } catch (InvalidArgumentException e) {
- assert false : e;
- }
+ model.setAttribute((org.netbeans.modules.xml.xdm.nodes.Element) el, "name", newBaseName); // NOI18N
}
- /*
- public boolean copy(String name, Transfer target, String targetName) throws IOException {
- if (! (target instanceof WritableXMLFileSystem)) return false;
- WritableXMLFileSystem otherfs = (WritableXMLFileSystem) target;
+ public @Override Enumeration attributes(String name) {
Element el = findElement(name);
- if (el == null) throw new FileNotFoundException(name);
- Element el2;
- if (otherfs == this) {
- el2 = (Element) el.cloneNode(true);
- } else {
- el2 = (Element) otherfs.doc.importNode(el, true);
- }
- String path, base;
- int idx = targetName.lastIndexOf('/');
- if (idx == -1) {
- path = ""; // NOI18N
- base = targetName;
- } else {
- path = targetName.substring(0, idx);
- base = targetName.substring(idx + 1);
- }
- Element parent = otherfs.findElement(path);
- if (parent == null) throw new FileNotFoundException(path);
- el2.setAttribute("name", base); // NOI18N
- Element old = otherfs.findElement(targetName);
- if (old != null) {
- parent.replaceChild(el2, old);
- } else {
- appendWithIndent(parent, el2);
- }
- return true;
- }
-
- public boolean move(String name, Transfer target, String targetName) throws IOException {
- if (! (target instanceof WritableXMLFileSystem)) return false;
- WritableXMLFileSystem otherfs = (WritableXMLFileSystem) target;
- Element el = findElement(name);
- if (el == null) throw new FileNotFoundException(name);
- Element el2;
- if (otherfs == this) {
- // Just move it, no need to clone.
- el2 = el;
- } else {
- el2 = (Element) otherfs.doc.importNode(el, true);
- }
- String path, base;
- int idx = targetName.lastIndexOf('/');
- if (idx == -1) {
- path = ""; // NOI18N
- base = targetName;
- } else {
- path = targetName.substring(0, idx);
- base = targetName.substring(idx + 1);
- }
- Element parent = otherfs.findElement(path);
- if (parent == null) throw new FileNotFoundException(path);
- el2.setAttribute("name", base); // NOI18N
- Element old = otherfs.findElement(targetName);
- if (el != el2) {
- // Cross-document import, so need to remove old one.
- el.getParentNode().removeChild(el);
- }
- if (old != null) {
- parent.replaceChild(el2, old);
- } else {
- appendWithIndent(parent, el2);
- }
- return true;
- }
- */
-
- public Enumeration attributes(String name) {
- TreeElement el = findElement(name);
if (el == null) {
return Enumerations.empty();
}
java.util.List l = new ArrayList(10);
- Iterator it = el.getChildNodes(TreeElement.class).iterator();
- while (it.hasNext()) {
- TreeElement sub = (TreeElement) it.next();
- if (sub.getLocalName().equals("attr")) { // NOI18N
- TreeAttribute nameAttr = sub.getAttribute("name"); // NOI18N
- if (nameAttr == null) {
+ for (Element sub : XMLUtil.findSubElements(el)) {
+ if (sub.getTagName().equals("attr")) { // NOI18N
+ String nameAttr = sub.getAttribute("name"); // NOI18N
+ if (nameAttr.isEmpty()) {
// Malformed.
continue;
}
- l.add(nameAttr.getValue());
+ l.add(nameAttr);
}
}
return Collections.enumeration(l);
}
- public Object readAttribute(String name, String attrName) {
+ public @Override Object readAttribute(String name, String attrName) {
if (attrName.equals("WritableXMLFileSystem.cp")) { // NOI18N
// XXX currently unused
return classpath;
@@ -589,9 +465,9 @@
return new URL[] {location};
}
if (attrName.equals("DataFolder.Index.reorderable")) { // NOI18N
- return Boolean.TRUE;
+ return true; // XXX is this still needed?
}
- TreeElement el = findElement(name);
+ Element el = findElement(name);
if (el == null) {
return null;
}
@@ -600,29 +476,22 @@
attrName = attrName.substring("literal:".length()); // NOI18N
literal = true;
}
- Iterator it = el.getChildNodes(TreeElement.class).iterator();
- while (it.hasNext()) {
- TreeElement sub = (TreeElement) it.next();
- if (!sub.getLocalName().equals("attr")) { // NOI18N
+ for (Element sub : XMLUtil.findSubElements(el)) {
+ if (!sub.getTagName().equals("attr")) { // NOI18N
continue;
}
- TreeAttribute nameAttr = sub.getAttribute("name"); // NOI18N
- if (nameAttr == null) {
- // Malformed.
- continue;
- }
- if (!attrName.equals(nameAttr.getValue())) {
+ if (!attrName.equals(sub.getAttribute("name"))) { // NOI18N
continue;
}
try {
- if ((nameAttr = sub.getAttribute("stringvalue")) != null) { // NOI18N
+ String val = sub.getAttribute("stringvalue"); // NOI18N
+ if (!val.isEmpty()) {
// Stolen from XMLMapAttr, with tweaks:
- String inStr = nameAttr.getValue();
- StringBuffer outStr = new StringBuffer(inStr.length());
- for (int j = 0; j < inStr.length(); j++) {
- char ch = inStr.charAt(j);
- if (ch == '\\' && inStr.charAt(j + 1) == 'u' && j + 5 < inStr.length()) {
- String hex = inStr.substring(j + 2, j + 6);
+ StringBuilder outStr = new StringBuilder(val.length());
+ for (int j = 0; j < val.length(); j++) {
+ char ch = val.charAt(j);
+ if (ch == '\\' && val.charAt(j + 1) == 'u' && j + 5 < val.length()) {
+ String hex = val.substring(j + 2, j + 6);
try {
outStr.append((char) Integer.parseInt(hex, 16));
j += 5;
@@ -635,36 +504,36 @@
}
}
return outStr.toString();
- } else if ((nameAttr = sub.getAttribute("boolvalue")) != null) { // NOI18N
- return Boolean.valueOf(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("urlvalue")) != null) { // NOI18N
- return new URL(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("charvalue")) != null) { // NOI18N
- return new Character(nameAttr.getValue().charAt(0));
- } else if ((nameAttr = sub.getAttribute("bytevalue")) != null) { // NOI18N
- return Byte.valueOf(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("shortvalue")) != null) { // NOI18N
- return Short.valueOf(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("intvalue")) != null) { // NOI18N
- return Integer.valueOf(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("longvalue")) != null) { // NOI18N
- return Long.valueOf(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("floatvalue")) != null) { // NOI18N
- return Float.valueOf(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("doublevalue")) != null) { // NOI18N
- return Double.valueOf(nameAttr.getValue());
- } else if ((nameAttr = sub.getAttribute("newvalue")) != null) { // NOI18N
- String clazz = nameAttr.getValue();
+ } else if (!(val = sub.getAttribute("boolvalue")).isEmpty()) { // NOI18N
+ return Boolean.valueOf(val);
+ } else if (!(val = sub.getAttribute("urlvalue")).isEmpty()) { // NOI18N
+ return new URL(val);
+ } else if (!(val = sub.getAttribute("charvalue")).isEmpty()) { // NOI18N
+ return Character.valueOf(val.charAt(0));
+ } else if (!(val = sub.getAttribute("bytevalue")).isEmpty()) { // NOI18N
+ return Byte.valueOf(val);
+ } else if (!(val = sub.getAttribute("shortvalue")).isEmpty()) { // NOI18N
+ return Short.valueOf(val);
+ } else if (!(val = sub.getAttribute("intvalue")).isEmpty()) { // NOI18N
+ return Integer.valueOf(val);
+ } else if (!(val = sub.getAttribute("longvalue")).isEmpty()) { // NOI18N
+ return Long.valueOf(val);
+ } else if (!(val = sub.getAttribute("floatvalue")).isEmpty()) { // NOI18N
+ return Float.valueOf(val);
+ } else if (!(val = sub.getAttribute("doublevalue")).isEmpty()) { // NOI18N
+ return Double.valueOf(val);
+ } else if (!(val = sub.getAttribute("newvalue")).isEmpty()) { // NOI18N
+ String clazz = val;
if (literal) {
return "new:" + clazz; // NOI18N
} // else XXX
- } else if ((nameAttr = sub.getAttribute("methodvalue")) != null) { // NOI18N
- String clazz = nameAttr.getValue();
+ } else if (!(val = sub.getAttribute("methodvalue")).isEmpty()) { // NOI18N
+ String clazz = val;
if (literal) {
return "method:" + clazz; // NOI18N
} // else XXX
- } else if ((nameAttr = sub.getAttribute("bundlevalue")) != null) { // NOI18N
- String bundle = nameAttr.getValue();
+ } else if (!(val = sub.getAttribute("bundlevalue")).isEmpty()) { // NOI18N
+ String bundle = val;
if (literal) {
return "bundle:" + bundle; // NOI18N
} else {
@@ -680,22 +549,6 @@
}
return null;
/*
- if ((v = sub.getAttributeNode("bytevalue")) != null) { // NOI18N
- return new Byte(v.getValue());
- } else if ((v = sub.getAttributeNode("shortvalue")) != null) { // NOI18N
- return new Short(v.getValue());
- } else if ((v = sub.getAttributeNode("intvalue")) != null) { // NOI18N
- return new Integer(v.getValue());
- } else if ((v = sub.getAttributeNode("longvalue")) != null) { // NOI18N
- return new Long(v.getValue());
- } else if ((v = sub.getAttributeNode("floatvalue")) != null) { // NOI18N
- return new Float(v.getValue());
- } else if ((v = sub.getAttributeNode("doublevalue")) != null) { // NOI18N
- // When was the last time you set a file attribute to a double?!
- // Useless list of primitives...
- return new Double(v.getValue());
- } else if ((v = sub.getAttributeNode("charvalue")) != null) { // NOI18N
- return new Character(v.getValue().charAt(0));
} else if ((v = sub.getAttributeNode("methodvalue")) != null) { // NOI18N
String value = v.getValue();
Object[] params = new Object[] { findResource(name), attrName };
@@ -812,113 +665,82 @@
*/
}
- public void writeAttribute(String name, String attrName, Object v) throws IOException {
+ public @Override void writeAttribute(String name, String attrName, Object v) throws IOException {
//System.err.println("wA: " + name + " " + attrName + " " + v);
if (v != null && v.getClass().getName().equals("org.openide.filesystems.MultiFileObject$VoidValue")) { // NOI18N
// XXX is this legitimate? Definitely not pretty. But needed for testOpenideFolderOrder to pass.
v = null;
}
- TreeElement el = findElement(name);
+ Element el = findElement(name);
if (el == null) {
throw new FileNotFoundException(name);
}
// Find any existing .
- TreeChild existingAttr = null;
- Iterator it = el.getChildNodes(TreeElement.class).iterator();
- while (it.hasNext()) {
- TreeElement sub = (TreeElement) it.next();
- if (sub.getLocalName().equals("attr")) { // NOI18N
- TreeAttribute attr = sub.getAttribute("name"); // NOI18N
- if (attr == null) {
- // Malformed.
- continue;
- }
- if (attr.getValue().equals(attrName)) {
- existingAttr = sub;
- break;
- }
+ Element existingAttr = null;
+ for (Element sub : XMLUtil.findSubElements(el)) {
+ if (sub.getTagName().equals("attr") && sub.getAttribute("name").equals(attrName)) { // NOI18N
+ existingAttr = sub;
+ break;
}
}
- TreeElement attr;
- try {
- attr = new TreeElement("attr", true); // NOI18N
- attr.addAttribute("name", attrName); // NOI18N
- if (v instanceof String) {
- String inStr = (String) v;
- final String newValueMagic = "newvalue:"; // NOI18N
- final String methodValueMagic = "methodvalue:"; // NOI18N
- final String bundleValueMagic = "bundlevalue:"; // NOI18N
- if (inStr.startsWith(newValueMagic)) {
- // Impossible to set this (reliably) as a real value, so use this magic technique instead:
- attr.addAttribute("newvalue", inStr.substring(newValueMagic.length())); // NOI18N
- } else if (inStr.startsWith(methodValueMagic)) {
- // Same here:
- attr.addAttribute("methodvalue", inStr.substring(methodValueMagic.length())); // NOI18N
- } else if (inStr.startsWith(bundleValueMagic)) {
- // Same here:
- attr.addAttribute("bundlevalue", inStr.substring(bundleValueMagic.length())); // NOI18N
- TreeObjectList nodes = doc.getChildNodes();
- for (int i = 0; i < nodes.size(); i++) {
- Object object = nodes.get(i);
- if (object instanceof TreeDocumentType) {
- TreeDocumentType tdt = (TreeDocumentType)object;
- tdt.setPublicId("-//NetBeans//DTD Filesystem 1.2//EN");
- tdt.setSystemId("http://www.netbeans.org/dtds/filesystem-1_2.dtd");
- break;
- }
+ Element attrE = el.getOwnerDocument().createElement("attr"); // NOI18N
+ attrE.setAttribute("name", attrName); // NOI18N
+ if (v instanceof String) {
+ String inStr = (String) v;
+ final String newValueMagic = "newvalue:"; // NOI18N
+ final String methodValueMagic = "methodvalue:"; // NOI18N
+ final String bundleValueMagic = "bundlevalue:"; // NOI18N
+ if (inStr.startsWith(newValueMagic)) {
+ // Impossible to set this (reliably) as a real value, so use this magic technique instead:
+ attrE.setAttribute("newvalue", inStr.substring(newValueMagic.length())); // NOI18N
+ } else if (inStr.startsWith(methodValueMagic)) {
+ // Same here:
+ attrE.setAttribute("methodvalue", inStr.substring(methodValueMagic.length())); // NOI18N
+ } else if (inStr.startsWith(bundleValueMagic)) {
+ // Same here:
+ attrE.setAttribute("bundlevalue", inStr.substring(bundleValueMagic.length())); // NOI18N
+ /* XXX figure out how to set DOCTYPE:
+ el.getOwnerDocument().getDoctype().setPublicId("-//NetBeans//DTD Filesystem 1.2//EN");
+ el.getOwnerDocument().getDoctype().setSystemId("http://www.netbeans.org/dtds/filesystem-1_2.dtd");
+ */
+ } else {
+ // Regular string value.
+ // Stolen from XMLMapAttr w/ mods:
+ StringBuilder outStr = new StringBuilder();
+ for (int i = 0; i < inStr.length(); i++) {
+ char c = inStr.charAt(i);
+ if (Character.isISOControl(c) || c == '&' || c == '<' || c == '>' || c == '"' || c == '\'') {
+ outStr.append(encodeChar(c));
+ } else {
+ outStr.append(c);
}
- } else {
- // Regular string value.
- // Stolen from XMLMapAttr w/ mods:
- StringBuffer outStr = new StringBuffer();
- for (int i = 0; i < inStr.length(); i++) {
- char c = inStr.charAt(i);
- if (Character.isISOControl(c) || c == '&' || c == '<' || c == '>' || c == '"' || c == '\'') {
- outStr.append(encodeChar(c));
- } else {
- outStr.append(c);
- }
- }
- attr.addAttribute("stringvalue", outStr.toString()); // NOI18N
}
- } else if (v instanceof URL) {
- attr.addAttribute("urlvalue", ((URL) v).toExternalForm()); // NOI18N
- } else if (v instanceof Boolean) {
- attr.addAttribute("boolvalue", v.toString()); // NOI18N
- } else if (v instanceof Character) {
- attr.addAttribute("charvalue", v.toString()); // NOI18N
- } else if (v instanceof Integer) {
- attr.addAttribute("intvalue", v.toString()); // NOI18N
- } else if (v != null) {
- throw new UnsupportedOperationException("XXX: " + v); // NOI18N
+ attrE.setAttribute("stringvalue", outStr.toString()); // NOI18N
}
- if (v != null && existingAttr == null) {
- appendWithIndent(el, attr);
- } else if (v != null) {
- ((TreeParentNode) el).replaceChild(existingAttr, attr);
- } else if (existingAttr != null) {
- deleteWithIndent(existingAttr);
- }
- } catch (InvalidArgumentException e) {
- throw new AssertionError(e);
- } catch (ReadOnlyException e) {
- throw (IOException) new IOException(e.toString()).initCause(e);
+ } else if (v instanceof URL) {
+ attrE.setAttribute("urlvalue", ((URL) v).toExternalForm()); // NOI18N
+ } else if (v instanceof Boolean) {
+ attrE.setAttribute("boolvalue", v.toString()); // NOI18N
+ } else if (v instanceof Character) {
+ attrE.setAttribute("charvalue", v.toString()); // NOI18N
+ } else if (v instanceof Integer) {
+ attrE.setAttribute("intvalue", v.toString()); // NOI18N
+ } else if (v != null) {
+ throw new UnsupportedOperationException("XXX: " + v); // NOI18N
+ }
+ if (v != null && existingAttr == null) {
+ model.insertBefore((org.netbeans.modules.xml.xdm.nodes.Node) el,
+ (org.netbeans.modules.xml.xdm.nodes.Node) attrE,
+ (org.netbeans.modules.xml.xdm.nodes.Node) findInsertionPosition(el, attrE));
+ } else if (v != null) {
+ model.replaceChild((org.netbeans.modules.xml.xdm.nodes.Node) el,
+ (org.netbeans.modules.xml.xdm.nodes.Node) attrE,
+ (org.netbeans.modules.xml.xdm.nodes.Node) existingAttr);
+ } else if (existingAttr != null) {
+ model.removeChildNodes((org.netbeans.modules.xml.xdm.nodes.Node) el,
+ Collections.singleton((org.netbeans.modules.xml.xdm.nodes.Node) existingAttr));
}
/*
- if (v instanceof Byte) {
- attr.setAttribute("bytevalue", v.toString()); // NOI18N
- } else if (v instanceof Short) {
- attr.setAttribute("shortvalue", v.toString()); // NOI18N
- } else if (v instanceof Integer) {
- attr.setAttribute("intvalue", v.toString()); // NOI18N
- } else if (v instanceof Long) {
- attr.setAttribute("longvalue", v.toString()); // NOI18N
- } else if (v instanceof Float) {
- attr.setAttribute("floatvalue", v.toString()); // NOI18N
- } else if (v instanceof Double) {
- attr.setAttribute("doublevalue", v.toString()); // NOI18N
- } else if (v instanceof Character) {
- attr.setAttribute("charvalue", v.toString()); // NOI18N
} else {
// Stolen from XMLMapAttr, mostly.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
@@ -1000,23 +822,23 @@
return "\\u" + "0000".substring(0, "0000".length() - encChar.length()).concat(encChar); // NOI18N
}
- public void renameAttributes(String oldName, String newName) {
+ public @Override void renameAttributes(String oldName, String newName) {
// do nothing
}
- public void deleteAttributes(String name) {
+ public @Override void deleteAttributes(String name) {
// do nothing
}
- public boolean readOnly(String name) {
+ public @Override boolean readOnly(String name) {
return false;
}
- public String mimeType(String name) {
+ public @Override String mimeType(String name) {
return null; // i.e. use default resolvers
}
- public long size(String name) {
+ public @Override long size(String name) {
try {
return getContentsOf(name).length;
} catch (FileNotFoundException fnfe) {
@@ -1024,20 +846,19 @@
}
}
- public void markUnimportant(String name) {
+ public @Override void markUnimportant(String name) {
// do nothing
}
- public Date lastModified(String name) {
- final TreeElement el = findElement(name);
+ public @Override Date lastModified(String name) {
+ final Element el = findElement(name);
if (el == null) {
return new Date(0L);
}
- TreeAttribute attr = el.getAttribute("url"); // NOI18N
- if (attr == null) {
+ String u = el.getAttribute("url"); // NOI18N
+ if (u.isEmpty()) {
return new Date(0L);
}
- String u = attr.getValue();
URI uri = null;
try {
uri = new URI(null, u, null);
@@ -1063,55 +884,16 @@
// These are not important for us:
- public void lock(String name) throws IOException {
+ public @Override void lock(String name) throws IOException {
// [PENDING] should this try to lock the XML document??
// (not clear if it is safe to do so from FS call, even tho
// on a different FS)
}
- public void unlock(String name) {
+ public @Override void unlock(String name) {
// do nothing
}
- // don't bother making configurable; or could use an indentation engine
- private static final int INDENT_STEP = 4;
- /**
- * Add a new element to a parent in the correct position.
- * Inserts whitespace to retain indentation rules.
- */
- private static void appendWithIndent(TreeElement parent, TreeChild child) throws ReadOnlyException {
- TreeParentNode doc = parent;
- int depth = -2; // will get then TreeDocument then null
- while (doc != null) {
- doc = ((TreeChild) doc).getParentNode();
- depth++;
- }
- TreeChild position = insertBefore(parent, child);
- try {
- if (position != null) {
- parent.insertBefore(child, position);
- parent.insertBefore(new TreeText("\n" + spaces((depth + 1) * INDENT_STEP)), position); // NOI18N
- } else {
- if (/*XXX this is clumsy*/ parent.hasChildNodes()) {
- parent.appendChild(new TreeText(spaces(INDENT_STEP)));
- } else {
- parent.appendChild(new TreeText("\n" + spaces((depth + 1) * INDENT_STEP))); // NOI18N
- }
- parent.appendChild(child);
- parent.appendChild(new TreeText("\n" + spaces(depth * INDENT_STEP))); // NOI18N
- }
- parent.normalize();
- /* XXX could check for adding position attr and resort parent of parent?
- TreeElement childe = (TreeElement) child;
- if (childe.getQName().equals("attr") && childe.getAttribute("name").getValue().indexOf('/') != -1) { // NOI18N
- // Check for ordering attributes, which we have to handle specially.
- resort(parent);
- }
- */
- } catch (InvalidArgumentException e) {
- assert false : e;
- }
- }
/**
* Find the proper location for a newly inserted element.
* Rules:
@@ -1119,269 +901,51 @@
* 2. must be added to top of element in alpha order w.r.t. existing ones.
* Returns a position to insert before (null for end).
*/
- private static TreeChild insertBefore(TreeElement parent, TreeChild child) throws ReadOnlyException {
- if (!(child instanceof TreeElement)) {
- return null; // TBD for now
- }
- TreeElement childe = (TreeElement) child;
- if (childe.getQName().equals("file") || childe.getQName().equals("folder")) { // NOI18N
- String name = childe.getAttribute("name").getValue(); // NOI18N
- Iterator it = parent.getChildNodes(TreeElement.class).iterator();
- while (it.hasNext()) {
- TreeElement kid = (TreeElement) it.next();
- if (kid.getQName().equals("file") || kid.getQName().equals("folder")) { // NOI18N
- TreeAttribute attr = kid.getAttribute("name"); // NOI18N
- if (attr != null) { // #66816 - layer might be malformed
- String kidname = attr.getValue();
- if (kidname.compareTo(name) > 0) {
- return kid;
- }
- }
+ private static Element findInsertionPosition(Element parent, Element child) {
+ if (child.getTagName().equals("file") || child.getTagName().equals("folder")) { // NOI18N
+ String name = child.getAttribute("name"); // NOI18N
+ for (Element kid : XMLUtil.findSubElements(parent)) {
+ if ((kid.getTagName().equals("file") || kid.getTagName().equals("folder")) && kid.getAttribute("name").compareTo(name) > 0) { // NOI18N
+ return kid;
}
}
return null;
- } else if (childe.getQName().equals("attr")) { // NOI18N
- String name = childe.getAttribute("name").getValue(); // NOI18N
- Iterator it = parent.getChildNodes(TreeElement.class).iterator();
- while (it.hasNext()) {
- TreeElement kid = (TreeElement) it.next();
- if (kid.getQName().equals("file") || kid.getQName().equals("folder")) { // NOI18N
+ } else if (child.getTagName().equals("attr")) { // NOI18N
+ String name = child.getAttribute("name"); // NOI18N
+ for (Element kid : XMLUtil.findSubElements(parent)) {
+ if (kid.getTagName().equals("file") || kid.getTagName().equals("folder")) { // NOI18N
return kid;
- } else if (kid.getQName().equals("attr")) { // NOI18N
- TreeAttribute attr = kid.getAttribute("name"); // NOI18N
- if (attr != null) {
- String kidname = attr.getValue();
- if (kidname.compareTo(name) > 0) {
- return kid;
- }
- }
- } else {
- throw new AssertionError("Weird child: " + kid.getQName());
+ } else if (kid.getTagName().equals("attr") && kid.getAttribute("name").compareTo(name) > 0) { // NOI18N
+ return kid;
}
}
return null;
} else {
- throw new AssertionError("Weird child: " + childe.getQName());
+ throw new AssertionError("Weird child: " + child.getTagName());
}
}
- /**
- * Resort all files and folders and attributes in a folder context. The order is:
- * 1. Attributes are alpha-sorted at the top.
- * 2. Files and folders are alpha-sorted if they have no position.
- * 3. Files with positions are sorted numerically above files without.
- */
- /* XXX not important yet
- private static void resort(TreeElement parent) throws ReadOnlyException {
- class Item {
- public TreeElement child;
- boolean isAttr() {
- return child.getQName().equals("attr"); // NOI18N
- }
- String getName() {
- TreeAttribute attr = child.getAttribute("name"); // NOI18N
- return attr != null ? attr.getValue() : "";
- }
- boolean isOrderingAttr() {
- return isAttr() && getName().indexOf('/') != -1;
- }
- String getFormer() {
- String n = getName();
- return n.substring(0, n.indexOf('/'));
- }
- String getLatter() {
- String n = getName();
- return n.substring(n.indexOf('/') + 1);
- }
- }
- Set- items = new LinkedHashSet();
- SortedSet indices = new TreeSet();
- for (int i = 0; i < parent.getChildrenNumber(); i++) {
- TreeChild child = (TreeChild) parent.getChildNodes().get(i);
- if (child instanceof TreeElement) {
- Item item = new Item();
- item.child = (TreeElement) child;
- items.add(item);
- indices.add(new Integer(i));
- }
- }
- Map
- > edges = new LinkedHashMap();
- Map filesAndFolders = new LinkedHashMap();
- Map attrs = new LinkedHashMap();
- Set orderedFilesAndFolders = new LinkedHashSet();
- Iterator it = items.iterator();
- while (it.hasNext()) {
- Item item = (Item) it.next();
- String name = item.getName();
- if (item.isAttr()) {
- attrs.put(name, item);
- if (item.isOrderingAttr()) {
- orderedFilesAndFolders.add(item.getFormer());
- orderedFilesAndFolders.add(item.getLatter());
- }
- } else {
- filesAndFolders.put(name, item);
- }
- }
- class NameComparator implements Comparator {
- public int compare(Object o1, Object o2) {
- Item i1 = (Item) o1;
- Item i2 = (Item) o2;
- return i1.getName().compareTo(i2.getName());
- }
- }
- Set
- sortedAttrs = new TreeSet(new NameComparator());
- Set
- sortedFilesAndFolders = new TreeSet(new NameComparator());
- Set
- orderableItems = new LinkedHashSet();
- it = items.iterator();
- while (it.hasNext()) {
- Item item = (Item) it.next();
- String name = item.getName();
- if (item.isAttr()) {
- if (item.isOrderingAttr()) {
- Item former = (Item) filesAndFolders.get(item.getFormer());
- if (former != null) {
- Set
- formerConstraints = (Set) edges.get(former);
- if (formerConstraints == null) {
- formerConstraints = new LinkedHashSet();
- edges.put(former, formerConstraints);
- }
- formerConstraints.add(item);
- }
- Item latter = (Item) filesAndFolders.get(item.getLatter());
- if (latter != null) {
- Set
- constraints = new LinkedHashSet();
- constraints.add(latter);
- edges.put(item, constraints);
- }
- orderableItems.add(item);
- } else {
- sortedAttrs.add(item);
- }
- } else {
- if (orderedFilesAndFolders.contains(name)) {
- orderableItems.add(item);
- } else {
- sortedFilesAndFolders.add(item);
- }
- }
- }
- java.util.List
- orderedItems;
- try {
- orderedItems = Utilities.topologicalSort(orderableItems, edges);
- } catch (TopologicalSortException e) {
- // OK, ignore.
- return;
- }
- it = items.iterator();
- while (it.hasNext()) {
- Item item = (Item) it.next();
- parent.removeChild(item.child);
- }
- java.util.List
- allOrderedItems = new ArrayList(sortedAttrs);
- allOrderedItems.addAll(orderedItems);
- allOrderedItems.addAll(sortedFilesAndFolders);
- assert new HashSet(allOrderedItems).equals(items);
- it = allOrderedItems.iterator();
- Iterator indexIt = indices.iterator();
- while (it.hasNext()) {
- Item item = (Item) it.next();
- int index = ((Integer) indexIt.next()).intValue();
- parent.insertChildAt(item.child, index);
- }
- }
- */
- private static String spaces(int size) {
- char[] chars = new char[size];
- for (int i = 0; i < size; i++) {
- chars[i] = ' ';
- }
- return new String(chars);
- }
- /**
- * Remove an element (and its children), deleting any surrounding newlines and indentation too.
- */
- private static void deleteWithIndent(TreeChild child) throws ReadOnlyException {
- TreeChild next = child.getNextSibling();
- // XXX better might be to delete any maximal [ \t]+ previous plus \n next (means splitting up TreeText's)
- if (next instanceof TreeText && ((TreeText) next).getData().matches("(\r|\n|\r\n)[ \t]+")) { // NOI18N
- next.removeFromContext();
- } else {
- TreeChild previous = child.getPreviousSibling();
- if (previous instanceof TreeText && ((TreeText) previous).getData().matches("(\r|\n|\r\n)[ \t]+")) { // NOI18N
- previous.removeFromContext();
- } else {
- // Well, not sure what is here, so skip it.
- }
- }
- TreeElement parent = (TreeElement) child.getParentNode();
- TreeObjectList list = parent.getChildNodes();
- boolean kill = true;
- Iterator it = list.iterator();
- while (it.hasNext()) {
- Object o = it.next();
- if (o == child) {
- continue;
- }
- if (!(o instanceof TreeText)) {
- kill = false;
- break;
- }
- if (((TreeText) o).getData().trim().length() > 0) {
- kill = false;
- break;
- }
- }
- if (kill) {
- try {
- // Special case for root of filesystem.
- if (((TreeChild) parent).getParentNode() instanceof TreeDocumentRoot) {
- it = list.iterator();
- while (it.hasNext()) {
- ((TreeChild) it.next()).removeFromContext();
- }
- parent.appendChild(new TreeText("\n")); // NOI18N
- } else {
- // Make sure we convert it to an empty tag (seems to only affect elements
- // which were originally parsed?):
- TreeElement parent2 = new TreeElement(parent.getQName(), true);
- TreeAttribute attr = parent.getAttribute("name"); // NOI18N
- if (attr != null) {
- parent2.addAttribute("name", attr.getValue()); // NOI18N
- }
- TreeParentNode grandparent = ((TreeChild) parent).getParentNode();
- // TreeElement.empty is sticky - cannot be changed retroactively (argh!).
- grandparent.replaceChild(parent, parent2);
- parent = parent2; // for normalize() below
- }
- } catch (InvalidArgumentException e) {
- assert false : e;
- }
- }
- child.removeFromContext();
- parent.normalize();
- }
// Listen to changes in files used as url= external contents. If these change,
// the filesystem needs to show something else. Properly we would
// keep track of *which* file changed and thus which of our resources
// is affected. Practically this would be a lot of work and gain
// very little.
- public void fileDeleted(FileEvent fe) {
+ public @Override void fileDeleted(FileEvent fe) {
someFileChange();
}
- public void fileFolderCreated(FileEvent fe) {
+ public @Override void fileFolderCreated(FileEvent fe) {
// does not apply to us
}
- public void fileDataCreated(FileEvent fe) {
+ public @Override void fileDataCreated(FileEvent fe) {
// not interesting here
}
- public void fileAttributeChanged(FileAttributeEvent fe) {
+ public @Override void fileAttributeChanged(FileAttributeEvent fe) {
// don't care about attributes on included files...
}
- public void fileRenamed(FileRenameEvent fe) {
+ public @Override void fileRenamed(FileRenameEvent fe) {
someFileChange();
}
- public void fileChanged(FileEvent fe) {
+ public @Override void fileChanged(FileEvent fe) {
someFileChange();
}
private void someFileChange() {
@@ -1389,14 +953,14 @@
refreshResource("", true);
}
- public void propertyChange(PropertyChangeEvent evt) {
- if (!evt.getPropertyName().equals(TreeEditorCookie.PROP_DOCUMENT_ROOT)) {
- return;
- }
- if (cookie.getStatus() == TreeEditorCookie.STATUS_OK || cookie.getStatus() == TreeEditorCookie.STATUS_NOT) {
+ public @Override void propertyChange(PropertyChangeEvent evt) {
+ /* XXX do we need to synch periodically?
+ model.sync();
+ */
+ model.flush();
+ // XXX if supporting external changes:
+ if (false/*model.getStatus() == XDMModel.Status.STABLE*/) {
// Document was modified, and reparsed OK. See what changed.
- try {
- doc = cookie.openDocumentRoot();
/* Neither of the following work:
refreshResource("", true); // only works on root folder
refreshRoot(); // seems to do nothing at all
@@ -1409,11 +973,6 @@
}
//System.err.println("got changes; new files: " + Collections.list(getRoot().getChildren(true)));
//Thread.dumpStack();
- } catch (TreeException e) {
- Util.err.notify(ErrorManager.INFORMATIONAL, e);
- } catch (IOException e) {
- Util.err.notify(ErrorManager.INFORMATIONAL, e);
- }
}
}
diff --git a/apisupport.project/test/unit/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystemTest.java b/apisupport.project/test/unit/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystemTest.java
--- a/apisupport.project/test/unit/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystemTest.java
+++ b/apisupport.project/test/unit/src/org/netbeans/modules/apisupport/project/layers/WritableXMLFileSystemTest.java
@@ -56,7 +56,6 @@
import java.util.Set;
import org.netbeans.junit.RandomlyFails;
import org.netbeans.modules.apisupport.project.TestBase;
-import org.netbeans.modules.apisupport.project.layers.LayerUtils.SavableTreeEditorCookie;
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
import org.openide.filesystems.FileAttributeEvent;
import org.openide.filesystems.FileChangeListener;
@@ -123,8 +122,7 @@
Layer orig = new Layer("", files);
FileObject orgTest = FileUtil.createFolder(new File(orig.folder, "org/test"));
FileObject lf = orig.f.copy(orgTest, "layer", "xml");
- SavableTreeEditorCookie cookie = LayerUtils.cookieForFile(lf);
- FileSystem fs = new WritableXMLFileSystem(lf.getURL(), cookie,
+ FileSystem fs = new WritableXMLFileSystem(lf,
ClassPathSupport.createClassPath(new FileObject[] { FileUtil.toFileObject(orig.folder) } ));
FileObject x = fs.findResource("x");
assertNotNull(x);
@@ -677,7 +675,7 @@
private final class Layer {
private final File folder;
private final FileObject f;
- private LayerUtils.SavableTreeEditorCookie cookie;
+ private WritableXMLFileSystem fs;
/**
* Create a layer from a fixed bit of filesystem-DTD XML.
* Omit the ...> tag and just give the contents.
@@ -731,8 +729,7 @@
* Read the filesystem from the layer.
*/
public WritableXMLFileSystem read() throws Exception {
- cookie = LayerUtils.cookieForFile(f);
- return new WritableXMLFileSystem(f.getURL(), cookie, null);
+ return fs = new WritableXMLFileSystem(f, null);
}
/**
* Write the filesystem to the layer and retrieve the new contents.
@@ -742,7 +739,7 @@
return write(HEADER, FOOTER);
}
String write(String head, String foot) throws Exception {
- cookie.save();
+ fs.save();
String raw = TestBase.slurp(f);
for (int i = 1; i <= 2; i++) {
diff --git a/xml.tax/nbproject/project.xml b/xml.tax/nbproject/project.xml
--- a/xml.tax/nbproject/project.xml
+++ b/xml.tax/nbproject/project.xml
@@ -157,7 +157,6 @@