Lines 65-88
Link Here
|
65 |
import java.util.Date; |
65 |
import java.util.Date; |
66 |
import java.util.Enumeration; |
66 |
import java.util.Enumeration; |
67 |
import java.util.HashSet; |
67 |
import java.util.HashSet; |
68 |
import java.util.Iterator; |
|
|
69 |
import java.util.Set; |
68 |
import java.util.Set; |
70 |
import org.netbeans.api.java.classpath.ClassPath; |
69 |
import org.netbeans.api.java.classpath.ClassPath; |
71 |
import org.netbeans.modules.apisupport.project.Util; |
70 |
import org.netbeans.editor.BaseDocument; |
72 |
import org.netbeans.modules.xml.tax.cookies.TreeEditorCookie; |
71 |
import org.netbeans.modules.xml.xam.ModelSource; |
73 |
import org.netbeans.tax.InvalidArgumentException; |
72 |
import org.netbeans.modules.xml.xdm.XDMModel; |
74 |
import org.netbeans.tax.ReadOnlyException; |
73 |
import org.openide.cookies.EditorCookie; |
75 |
import org.netbeans.tax.TreeAttribute; |
|
|
76 |
import org.netbeans.tax.TreeCDATASection; |
77 |
import org.netbeans.tax.TreeChild; |
78 |
import org.netbeans.tax.TreeDocumentRoot; |
79 |
import org.netbeans.tax.TreeDocumentType; |
80 |
import org.netbeans.tax.TreeElement; |
81 |
import org.netbeans.tax.TreeException; |
82 |
import org.netbeans.tax.TreeObjectList; |
83 |
import org.netbeans.tax.TreeParentNode; |
84 |
import org.netbeans.tax.TreeText; |
85 |
import org.openide.ErrorManager; |
86 |
import org.openide.filesystems.AbstractFileSystem; |
74 |
import org.openide.filesystems.AbstractFileSystem; |
87 |
import org.openide.filesystems.FileAttributeEvent; |
75 |
import org.openide.filesystems.FileAttributeEvent; |
88 |
import org.openide.filesystems.FileChangeListener; |
76 |
import org.openide.filesystems.FileChangeListener; |
Lines 91-109
Link Here
|
91 |
import org.openide.filesystems.FileRenameEvent; |
79 |
import org.openide.filesystems.FileRenameEvent; |
92 |
import org.openide.filesystems.FileUtil; |
80 |
import org.openide.filesystems.FileUtil; |
93 |
import org.openide.filesystems.URLMapper; |
81 |
import org.openide.filesystems.URLMapper; |
|
|
82 |
import org.openide.loaders.DataObject; |
94 |
import org.openide.util.Enumerations; |
83 |
import org.openide.util.Enumerations; |
95 |
import org.openide.util.WeakListeners; |
84 |
import org.openide.util.lookup.Lookups; |
|
|
85 |
import org.openide.xml.XMLUtil; |
86 |
import org.w3c.dom.CharacterData; |
87 |
import org.w3c.dom.Element; |
88 |
import org.w3c.dom.Node; |
89 |
import org.w3c.dom.NodeList; |
96 |
|
90 |
|
97 |
/** |
91 |
/** |
98 |
* A filesystem which is based on a TAX document and implements |
92 |
* A filesystem which is based on an XML document and implements |
99 |
* the same syntax as XMLFileSystem, from which inspiration is taken. |
93 |
* the same syntax as XMLFileSystem, from which inspiration is taken. |
100 |
* Not implemented similarly to XMLFileSystem because this is writable |
94 |
* Not implemented similarly to XMLFileSystem because this is writable |
101 |
* and designed specifically to write human-readable XML and work nicely |
95 |
* and designed specifically to write human-readable XML and work nicely |
102 |
* as an authoring tool. The filesystem expects to get an XML document |
96 |
* as an authoring tool. The filesystem expects to get an XML document |
103 |
* according to DTD "-//NetBeans//DTD Filesystem 1.0//EN" (or 1.1 is OK). |
97 |
* according to DTD "-//NetBeans//DTD Filesystem 1.0//EN" (or 1.1 or 1.2 is OK). |
104 |
* When it is changed via FileSystems API, it will fire TAX |
98 |
* When it is changed via the FileSystems API, it will update the document. |
105 |
* events. Not intended to be efficient or terribly robust, since it |
99 |
* Not intended to be efficient or terribly robust, since it is development-time only. |
106 |
* is development-time only. |
|
|
107 |
* @author Jesse Glick |
100 |
* @author Jesse Glick |
108 |
*/ |
101 |
*/ |
109 |
public final class WritableXMLFileSystem extends AbstractFileSystem |
102 |
public final class WritableXMLFileSystem extends AbstractFileSystem |
Lines 111-147
Link Here
|
111 |
AbstractFileSystem.Change, |
104 |
AbstractFileSystem.Change, |
112 |
AbstractFileSystem.Info, |
105 |
AbstractFileSystem.Info, |
113 |
AbstractFileSystem.List, |
106 |
AbstractFileSystem.List, |
114 |
//AbstractFileSystem.Transfer, |
|
|
115 |
FileChangeListener, |
107 |
FileChangeListener, |
116 |
PropertyChangeListener { |
108 |
PropertyChangeListener { |
117 |
|
109 |
|
118 |
private final TreeEditorCookie cookie; |
110 |
private final EditorCookie editorCookie; |
119 |
private TreeDocumentRoot doc; // may be null if malformed |
111 |
private final XDMModel model; |
120 |
private URL location; |
112 |
private URL location; |
121 |
private String suffix; // for branding/localization like "_f4j_ce_ja"; never null, at worst "" |
|
|
122 |
private final FileChangeListener fileChangeListener; |
113 |
private final FileChangeListener fileChangeListener; |
123 |
private ClassPath classpath; // OK to be null |
114 |
private ClassPath classpath; // OK to be null |
124 |
|
115 |
|
125 |
public WritableXMLFileSystem(URL location, TreeEditorCookie cookie, ClassPath classpath) { |
116 |
@SuppressWarnings("LeakingThisInConstructor") |
126 |
this.attr = this; |
117 |
public WritableXMLFileSystem(FileObject xml, ClassPath classpath) throws IOException { |
127 |
this.change = this; |
118 |
editorCookie = DataObject.find(xml).getLookup().lookup(EditorCookie.class); |
128 |
this.info = this; |
119 |
if (editorCookie == null) { |
129 |
this.list = this; |
120 |
throw new IOException("Noneditable layer: " + xml); |
130 |
//this.transfer = this; |
|
|
131 |
this.cookie = cookie; |
132 |
suffix = ""; |
133 |
try { |
134 |
doc = cookie.openDocumentRoot(); |
135 |
} catch (TreeException e) { |
136 |
Util.err.notify(ErrorManager.INFORMATIONAL, e); |
137 |
} catch (IOException e) { |
138 |
Util.err.notify(ErrorManager.INFORMATIONAL, e); |
139 |
} |
121 |
} |
|
|
122 |
model = new XDMModel(new ModelSource(Lookups.fixed(xml, (BaseDocument) editorCookie.openDocument()), true)); |
123 |
model.sync(); |
124 |
model.addPropertyChangeListener(this); |
125 |
model.setPretty(true); |
126 |
model.setIndentation(" "); // NOI18N |
127 |
attr = this; |
128 |
change = this; |
129 |
info = this; |
130 |
list = this; |
140 |
fileChangeListener = FileUtil.weakFileChangeListener(this, null); |
131 |
fileChangeListener = FileUtil.weakFileChangeListener(this, null); |
141 |
cookie.addPropertyChangeListener(WeakListeners.propertyChange(this, cookie)); |
132 |
setLocation(xml.getURL()); |
142 |
setLocation(location); |
|
|
143 |
setClasspath(classpath); |
133 |
setClasspath(classpath); |
144 |
} |
134 |
} |
|
|
135 |
|
136 |
/** |
137 |
* Saves any outstanding modifications to disk. |
138 |
* (Modifications are always applied immediately to an editor document.) |
139 |
* @throws IOException if the document could not be saved |
140 |
*/ |
141 |
public void save() throws IOException { |
142 |
editorCookie.saveDocument(); |
143 |
} |
145 |
|
144 |
|
146 |
private void writeObject(ObjectOutputStream out) throws IOException { |
145 |
private void writeObject(ObjectOutputStream out) throws IOException { |
147 |
throw new NotSerializableException("WritableXMLFileSystem is not persistent"); // NOI18N |
146 |
throw new NotSerializableException("WritableXMLFileSystem is not persistent"); // NOI18N |
Lines 159-165
Link Here
|
159 |
this.classpath = classpath; |
158 |
this.classpath = classpath; |
160 |
} |
159 |
} |
161 |
|
160 |
|
162 |
public String getDisplayName() { |
161 |
public @Override String getDisplayName() { |
163 |
FileObject fo = URLMapper.findFileObject(location); |
162 |
FileObject fo = URLMapper.findFileObject(location); |
164 |
if (fo != null) { |
163 |
if (fo != null) { |
165 |
return FileUtil.getFileDisplayName(fo); |
164 |
return FileUtil.getFileDisplayName(fo); |
Lines 168-202
Link Here
|
168 |
} |
167 |
} |
169 |
} |
168 |
} |
170 |
|
169 |
|
171 |
public boolean isReadOnly() { |
170 |
public @Override boolean isReadOnly() { |
172 |
return false; |
171 |
return false; |
173 |
} |
172 |
} |
174 |
|
173 |
|
175 |
private TreeElement getRootElement() { |
174 |
private Element getRootElement() { |
176 |
if (doc == null) { |
175 |
return model.getDocument().getDocumentElement(); |
177 |
return null; |
|
|
178 |
} |
179 |
Iterator it; |
180 |
it = doc.getChildNodes().iterator(); |
181 |
while (it.hasNext()) { |
182 |
Object next = it.next(); |
183 |
if (next instanceof TreeElement) { |
184 |
return (TreeElement) next; |
185 |
} |
186 |
} |
187 |
return null; |
188 |
} |
176 |
} |
189 |
|
177 |
|
190 |
/** Given a resource name, find the matching DOM element. |
178 |
/** Given a resource name, find the matching DOM element. |
191 |
* @return a <folder> or <file> or <filesystem> element, or null if file does not exist |
179 |
* @return a <folder> or <file> or <filesystem> element, or null if file does not exist |
192 |
*/ |
180 |
*/ |
193 |
private TreeElement findElement(String name) { |
181 |
private Element findElement(String name) { |
194 |
return findElementIn(getRootElement(), name); |
182 |
return findElementIn(getRootElement(), name); |
195 |
} |
183 |
} |
196 |
/** helper method only */ |
184 |
/** helper method only */ |
197 |
private static TreeElement findElementIn(TreeElement el, String name) { |
185 |
private static Element findElementIn(Element el, String name) { |
198 |
if (el == null) return null; |
186 |
if (el == null) { |
199 |
if (name.equals("")) { // NOI18N |
187 |
return null; |
|
|
188 |
} |
189 |
if (name.isEmpty()) { |
200 |
return el; |
190 |
return el; |
201 |
} else { |
191 |
} else { |
202 |
int idx = name.indexOf('/'); |
192 |
int idx = name.indexOf('/'); |
Lines 208-221
Link Here
|
208 |
nextName = name.substring(0, idx); |
198 |
nextName = name.substring(0, idx); |
209 |
remainder = name.substring(idx + 1); |
199 |
remainder = name.substring(idx + 1); |
210 |
} |
200 |
} |
211 |
TreeElement subel = null; |
201 |
Element subel = null; |
212 |
Iterator it = el.getChildNodes(TreeElement.class).iterator(); |
202 |
for (Element e : XMLUtil.findSubElements(el)) { |
213 |
while (it.hasNext()) { |
203 |
if (e.getTagName().equals("file") || // NOI18N |
214 |
TreeElement e = (TreeElement) it.next(); |
204 |
e.getTagName().equals("folder")) { // NOI18N |
215 |
if (e.getLocalName().equals("file") || // NOI18N |
205 |
String nameAttr = e.getAttribute("name"); // NOI18N |
216 |
e.getLocalName().equals("folder")) { // NOI18N |
206 |
if (nameAttr.equals(nextName)) { |
217 |
TreeAttribute nameAttr = e.getAttribute("name"); // NOI18N |
|
|
218 |
if (nameAttr != null && nameAttr.getValue().equals(nextName)) { |
219 |
subel = e; |
207 |
subel = e; |
220 |
break; |
208 |
break; |
221 |
} |
209 |
} |
Lines 225-277
Link Here
|
225 |
} |
213 |
} |
226 |
} |
214 |
} |
227 |
|
215 |
|
228 |
public boolean folder(String name) { |
216 |
public @Override boolean folder(String name) { |
229 |
TreeElement el = findElement(name); |
217 |
Element el = findElement(name); |
230 |
if (el == null) { |
218 |
if (el == null) { |
231 |
//System.err.println("folder <" + name + ">: false, no such element"); |
219 |
//System.err.println("folder <" + name + ">: false, no such element"); |
232 |
return false; |
220 |
return false; |
233 |
} |
221 |
} |
234 |
boolean res = el.getLocalName().equals("folder"); // NOI18N |
222 |
boolean res = el.getTagName().equals("folder"); // NOI18N |
235 |
//System.err.println("folder <" + name + ">: " + res); |
223 |
//System.err.println("folder <" + name + ">: " + res); |
236 |
return res; |
224 |
return res; |
237 |
} |
225 |
} |
238 |
|
226 |
|
239 |
/* |
227 |
public @Override String[] children(String f) { |
240 |
private static final Set warnedAboutDupeKids = new HashSet(1); // Set<String> |
228 |
Element el = findElement(f); |
241 |
*/ |
|
|
242 |
public String[] children(String f) { |
243 |
TreeElement el = findElement(f); |
244 |
if (el == null) { |
229 |
if (el == null) { |
245 |
//System.err.println("children <" + f + ">: none, no such element"); |
230 |
//System.err.println("children <" + f + ">: none, no such element"); |
246 |
return new String[] {}; |
231 |
return new String[] {}; |
247 |
} |
232 |
} |
248 |
ArrayList<String> kids = new ArrayList<String>(); |
233 |
ArrayList<String> kids = new ArrayList<String>(); |
249 |
Set<String> allNames = new HashSet<String>(); |
234 |
Set<String> allNames = new HashSet<String>(); |
250 |
Iterator it = el.getChildNodes(TreeElement.class).iterator(); |
235 |
for (Element sub : XMLUtil.findSubElements(el)) { |
251 |
while (it.hasNext()) { |
236 |
if (sub.getTagName().equals("file") || // NOI18N |
252 |
TreeElement sub = (TreeElement) it.next(); |
237 |
sub.getTagName().equals("folder")) { // NOI18N |
253 |
if (sub.getLocalName().equals("file") || // NOI18N |
238 |
String name = sub.getAttribute("name"); // NOI18N |
254 |
sub.getLocalName().equals("folder")) { // NOI18N |
239 |
if (name.isEmpty()) { |
255 |
TreeAttribute childName = sub.getAttribute("name"); // NOI18N |
|
|
256 |
if (childName == null) { |
257 |
continue; |
240 |
continue; |
258 |
} |
241 |
} |
259 |
String name = childName.getValue(); // NOI18N |
|
|
260 |
if (allNames.add(name)) { |
242 |
if (allNames.add(name)) { |
261 |
kids.add(name); |
243 |
kids.add(name); |
262 |
/* |
|
|
263 |
} else { |
264 |
if (warnedAboutDupeKids.add(location + ":" + f + "/" + name)) { // NOI18N |
265 |
// #18699: will deadlock if you try to change anything. |
266 |
if (f.equals("")) { // NOI18N |
267 |
LayerDataNode.getErr().println("WARNING: in " + xmlfile + " the root folder contains the child " + name + " more than once."); |
268 |
} else { |
269 |
LayerDataNode.getErr().println("WARNING: in " + xmlfile + " the folder " + f + " contains the child " + name + " more than once."); |
270 |
} |
271 |
//LayerDataNode.getErr().println("The Open APIs Support module will not work properly with such a layer."); |
272 |
//LayerDataNode.getErr().println("Please edit the XML text and merge together all children of a <folder> with the same name."); |
273 |
} |
274 |
*/ |
275 |
} |
244 |
} |
276 |
} |
245 |
} |
277 |
} |
246 |
} |
Lines 281-301
Link Here
|
281 |
|
250 |
|
282 |
/** retrieve byte contents of a named resource */ |
251 |
/** retrieve byte contents of a named resource */ |
283 |
private byte[] getContentsOf(final String name) throws FileNotFoundException { |
252 |
private byte[] getContentsOf(final String name) throws FileNotFoundException { |
284 |
TreeElement el = findElement(name); |
253 |
Element el = findElement(name); |
285 |
if (el == null) throw new FileNotFoundException(name); |
254 |
if (el == null) { |
286 |
TreeAttribute urlAttr = el.getAttribute("url"); // NOI18N |
255 |
throw new FileNotFoundException(name); |
287 |
if (urlAttr != null) { |
256 |
} |
|
|
257 |
String sURL = el.getAttribute("url"); // NOI18N |
258 |
if (!sURL.isEmpty()) { |
288 |
try { |
259 |
try { |
289 |
String sURL = urlAttr.getValue(); |
|
|
290 |
URI uri = new URI(null, sURL, null); |
260 |
URI uri = new URI(null, sURL, null); |
291 |
boolean nbmRelative = sURL.startsWith("nbres:") || sURL.startsWith("nbresloc:"); |
261 |
boolean nbmRelative = sURL.startsWith("nbres:") || sURL.startsWith("nbresloc:"); |
292 |
URL url = nbmRelative ? uri.toURL() : new URL(location, uri.getRawPath()); |
262 |
URL url = nbmRelative ? uri.toURL() : new URL(location, uri.getRawPath()); |
293 |
URL[] u = LayerUtils.currentify(url, suffix, classpath); |
263 |
URL[] u = LayerUtils.currentify(url, "", classpath); |
294 |
URLConnection conn = u[0].openConnection(); |
264 |
URLConnection conn = u[0].openConnection(); |
295 |
conn.connect(); |
265 |
conn.connect(); |
296 |
InputStream is = conn.getInputStream(); |
266 |
InputStream is = conn.getInputStream(); |
297 |
byte[] buf = new byte[conn.getContentLength()]; |
267 |
byte[] buf = new byte[conn.getContentLength()]; |
298 |
if (is.read(buf) != buf.length) throw new IOException("wrong content length"); // NOI18N |
268 |
if (is.read(buf) != buf.length) { |
|
|
269 |
throw new IOException("wrong content length"); |
270 |
} |
299 |
// Also listen to changes in it. |
271 |
// Also listen to changes in it. |
300 |
FileObject fo = URLMapper.findFileObject(u[0]); |
272 |
FileObject fo = URLMapper.findFileObject(u[0]); |
301 |
if (fo != null) { |
273 |
if (fo != null) { |
Lines 309-322
Link Here
|
309 |
throw new FileNotFoundException(use.getMessage()); |
281 |
throw new FileNotFoundException(use.getMessage()); |
310 |
} |
282 |
} |
311 |
} else { |
283 |
} else { |
312 |
StringBuffer buf = new StringBuffer(); |
284 |
StringBuilder buf = new StringBuilder(); |
313 |
Iterator it = el.getChildNodes().iterator(); |
285 |
NodeList nl = el.getChildNodes(); |
314 |
while (it.hasNext()) { |
286 |
for (int i = 0; i < nl.getLength(); i++) { |
315 |
Object o = it.next(); |
287 |
Node n = nl.item(i); |
316 |
if (o instanceof TreeCDATASection) { |
288 |
if (n.getNodeType() == Node.CDATA_SECTION_NODE || n.getNodeType() == Node.TEXT_NODE) { |
317 |
buf.append(((TreeCDATASection) o).getData()); |
289 |
buf.append(((CharacterData) n).getData()); |
318 |
} else if (o instanceof TreeText) { |
|
|
319 |
buf.append(((TreeText) o).getData().trim()); |
320 |
} |
290 |
} |
321 |
} |
291 |
} |
322 |
try { |
292 |
try { |
Lines 331-348
Link Here
|
331 |
// [PENDING] should I/O from/to external text files be done via EditorCookie? |
301 |
// [PENDING] should I/O from/to external text files be done via EditorCookie? |
332 |
// Not clear if this is safe (call from FS -> DS) even tho in separate FSs... |
302 |
// Not clear if this is safe (call from FS -> DS) even tho in separate FSs... |
333 |
|
303 |
|
334 |
public InputStream inputStream(String name) throws FileNotFoundException { |
304 |
public @Override InputStream inputStream(String name) throws FileNotFoundException { |
335 |
return new ByteArrayInputStream(getContentsOf(name)); |
305 |
return new ByteArrayInputStream(getContentsOf(name)); |
336 |
} |
306 |
} |
337 |
|
307 |
|
338 |
public OutputStream outputStream(final String name) throws IOException { |
308 |
public @Override OutputStream outputStream(final String name) throws IOException { |
339 |
final TreeElement el = findElement(name); |
309 |
final Element el = findElement(name); |
340 |
if (el == null) { |
310 |
if (el == null) { |
341 |
throw new FileNotFoundException(name); |
311 |
throw new FileNotFoundException(name); |
342 |
} |
312 |
} |
343 |
TreeAttribute urlAttr = el.getAttribute("url"); // NOI18N |
313 |
String u = el.getAttribute("url"); // NOI18N |
344 |
if (urlAttr != null) { |
314 |
if (!u.isEmpty()) { |
345 |
String u = urlAttr.getValue(); |
|
|
346 |
if (URI.create(u).isAbsolute()) { |
315 |
if (URI.create(u).isAbsolute()) { |
347 |
// What to do? Can't overwrite it, obviously. |
316 |
// What to do? Can't overwrite it, obviously. |
348 |
throw new IOException(name); |
317 |
throw new IOException(name); |
Lines 356-362
Link Here
|
356 |
} |
325 |
} |
357 |
// We will change the layer file. |
326 |
// We will change the layer file. |
358 |
return new ByteArrayOutputStream() { |
327 |
return new ByteArrayOutputStream() { |
359 |
public void close() throws IOException { |
328 |
public @Override void close() throws IOException { |
360 |
super.close(); |
329 |
super.close(); |
361 |
final byte[] contents = toByteArray(); |
330 |
final byte[] contents = toByteArray(); |
362 |
/* If desired to kill any existing inline content: |
331 |
/* If desired to kill any existing inline content: |
Lines 380-386
Link Here
|
380 |
final String externalName = LayerUtils.findGeneratedName(parent, name); |
349 |
final String externalName = LayerUtils.findGeneratedName(parent, name); |
381 |
assert externalName.indexOf('/') == -1 : externalName; |
350 |
assert externalName.indexOf('/') == -1 : externalName; |
382 |
parent.getFileSystem().runAtomicAction(new AtomicAction() { |
351 |
parent.getFileSystem().runAtomicAction(new AtomicAction() { |
383 |
public void run() throws IOException { |
352 |
public @Override void run() throws IOException { |
384 |
FileObject externalFile = parent.createData(externalName); |
353 |
FileObject externalFile = parent.createData(externalName); |
385 |
OutputStream os = externalFile.getOutputStream(); |
354 |
OutputStream os = externalFile.getOutputStream(); |
386 |
try { |
355 |
try { |
Lines 391-403
Link Here
|
391 |
externalFile.addFileChangeListener(fileChangeListener); |
360 |
externalFile.addFileChangeListener(fileChangeListener); |
392 |
} |
361 |
} |
393 |
}); |
362 |
}); |
394 |
try { |
363 |
model.setAttribute((org.netbeans.modules.xml.xdm.nodes.Element) el, "url", externalName); // NOI18N |
395 |
el.addAttribute("url", externalName); // NOI18N |
|
|
396 |
} catch (ReadOnlyException e) { |
397 |
throw (IOException) new IOException(e.toString()).initCause(e); |
398 |
} catch (InvalidArgumentException e) { |
399 |
assert false : e; |
400 |
} |
401 |
} |
364 |
} |
402 |
}; |
365 |
}; |
403 |
} |
366 |
} |
Lines 422-473
Link Here
|
422 |
parentName = name.substring(0, idx); |
385 |
parentName = name.substring(0, idx); |
423 |
baseName = name.substring(idx + 1); |
386 |
baseName = name.substring(idx + 1); |
424 |
} |
387 |
} |
425 |
TreeElement el = findElement(parentName); |
388 |
Element el = findElement(parentName); |
426 |
if (el == null) { |
389 |
if (el == null) { |
427 |
throw new FileNotFoundException(parentName); |
390 |
throw new FileNotFoundException(parentName); |
428 |
} |
391 |
} |
429 |
try { |
392 |
Element nue = el.getOwnerDocument().createElement(folder ? "folder" : "file"); // NOI18N |
430 |
TreeElement nue = new TreeElement(folder ? "folder" : "file", true); // NOI18N |
393 |
nue.setAttribute("name", baseName); // NOI18N |
431 |
nue.addAttribute("name", baseName); // NOI18N |
394 |
model.insertBefore((org.netbeans.modules.xml.xdm.nodes.Node) el, |
432 |
appendWithIndent(el, nue); |
395 |
(org.netbeans.modules.xml.xdm.nodes.Node) nue, |
433 |
} catch (InvalidArgumentException e) { |
396 |
(org.netbeans.modules.xml.xdm.nodes.Node) findInsertionPosition(el, nue)); |
434 |
assert false : e; |
|
|
435 |
} catch (ReadOnlyException e) { |
436 |
throw (IOException) new IOException(e.toString()).initCause(e); |
437 |
} |
438 |
} |
397 |
} |
439 |
|
398 |
|
440 |
public void createFolder(String name) throws IOException { |
399 |
public @Override void createFolder(String name) throws IOException { |
441 |
createFileOrFolder(name, true); |
400 |
createFileOrFolder(name, true); |
442 |
} |
401 |
} |
443 |
|
402 |
|
444 |
public void createData(String name) throws IOException { |
403 |
public @Override void createData(String name) throws IOException { |
445 |
createFileOrFolder(name, false); |
404 |
createFileOrFolder(name, false); |
446 |
} |
405 |
} |
447 |
|
406 |
|
448 |
public void delete(String name) throws IOException { |
407 |
public @Override void delete(String name) throws IOException { |
449 |
TreeElement el = findElement(name); |
408 |
Element el = findElement(name); |
450 |
if (el == null) { |
409 |
if (el == null) { |
451 |
throw new FileNotFoundException(name); |
410 |
throw new FileNotFoundException(name); |
452 |
} |
411 |
} |
453 |
TreeAttribute externalName = el.getAttribute("url"); // NOI18N |
412 |
String externalName = el.getAttribute("url"); // NOI18N |
454 |
if (externalName != null && !URI.create(externalName.getValue()).isAbsolute()) { |
413 |
if (!externalName.isEmpty() && !URI.create(externalName).isAbsolute()) { |
455 |
// Delete the external file if it can be found. |
414 |
// Delete the external file if it can be found. |
456 |
FileObject externalFile = URLMapper.findFileObject(new URL(location, externalName.getValue())); |
415 |
FileObject externalFile = URLMapper.findFileObject(new URL(location, externalName)); |
457 |
if (externalFile != null) { |
416 |
if (externalFile != null) { |
458 |
externalFile.removeFileChangeListener(fileChangeListener); |
417 |
externalFile.removeFileChangeListener(fileChangeListener); |
459 |
externalFile.delete(); |
418 |
externalFile.delete(); |
460 |
} |
419 |
} |
461 |
} |
420 |
} |
462 |
try { |
421 |
model.removeChildNodes((org.netbeans.modules.xml.xdm.nodes.Node) el.getParentNode(), Collections.singleton((org.netbeans.modules.xml.xdm.nodes.Node) el)); |
463 |
deleteWithIndent((TreeChild) el); |
|
|
464 |
} catch (ReadOnlyException e) { |
465 |
throw (IOException) new IOException(e.toString()).initCause(e); |
466 |
} |
467 |
} |
422 |
} |
468 |
|
423 |
|
469 |
public void rename(String oldName, String newName) throws IOException { |
424 |
public @Override void rename(String oldName, String newName) throws IOException { |
470 |
TreeElement el = findElement(oldName); |
425 |
Element el = findElement(oldName); |
471 |
if (el == null) { |
426 |
if (el == null) { |
472 |
throw new FileNotFoundException(oldName); |
427 |
throw new FileNotFoundException(oldName); |
473 |
} |
428 |
} |
Lines 478-585
Link Here
|
478 |
String newBaseName = newName.substring(idx); |
433 |
String newBaseName = newName.substring(idx); |
479 |
assert newBaseName.indexOf('/') == -1; |
434 |
assert newBaseName.indexOf('/') == -1; |
480 |
assert newBaseName.length() > 0; |
435 |
assert newBaseName.length() > 0; |
481 |
try { |
436 |
model.setAttribute((org.netbeans.modules.xml.xdm.nodes.Element) el, "name", newBaseName); // NOI18N |
482 |
el.getAttribute("name").setValue(newBaseName); // NOI18N |
|
|
483 |
} catch (ReadOnlyException e) { |
484 |
throw (IOException) new IOException(e.toString()).initCause(e); |
485 |
} catch (InvalidArgumentException e) { |
486 |
assert false : e; |
487 |
} |
488 |
} |
437 |
} |
489 |
|
438 |
|
490 |
/* |
439 |
public @Override Enumeration<String> attributes(String name) { |
491 |
public boolean copy(String name, Transfer target, String targetName) throws IOException { |
|
|
492 |
if (! (target instanceof WritableXMLFileSystem)) return false; |
493 |
WritableXMLFileSystem otherfs = (WritableXMLFileSystem) target; |
494 |
Element el = findElement(name); |
440 |
Element el = findElement(name); |
495 |
if (el == null) throw new FileNotFoundException(name); |
|
|
496 |
Element el2; |
497 |
if (otherfs == this) { |
498 |
el2 = (Element) el.cloneNode(true); |
499 |
} else { |
500 |
el2 = (Element) otherfs.doc.importNode(el, true); |
501 |
} |
502 |
String path, base; |
503 |
int idx = targetName.lastIndexOf('/'); |
504 |
if (idx == -1) { |
505 |
path = ""; // NOI18N |
506 |
base = targetName; |
507 |
} else { |
508 |
path = targetName.substring(0, idx); |
509 |
base = targetName.substring(idx + 1); |
510 |
} |
511 |
Element parent = otherfs.findElement(path); |
512 |
if (parent == null) throw new FileNotFoundException(path); |
513 |
el2.setAttribute("name", base); // NOI18N |
514 |
Element old = otherfs.findElement(targetName); |
515 |
if (old != null) { |
516 |
parent.replaceChild(el2, old); |
517 |
} else { |
518 |
appendWithIndent(parent, el2); |
519 |
} |
520 |
return true; |
521 |
} |
522 |
|
523 |
public boolean move(String name, Transfer target, String targetName) throws IOException { |
524 |
if (! (target instanceof WritableXMLFileSystem)) return false; |
525 |
WritableXMLFileSystem otherfs = (WritableXMLFileSystem) target; |
526 |
Element el = findElement(name); |
527 |
if (el == null) throw new FileNotFoundException(name); |
528 |
Element el2; |
529 |
if (otherfs == this) { |
530 |
// Just move it, no need to clone. |
531 |
el2 = el; |
532 |
} else { |
533 |
el2 = (Element) otherfs.doc.importNode(el, true); |
534 |
} |
535 |
String path, base; |
536 |
int idx = targetName.lastIndexOf('/'); |
537 |
if (idx == -1) { |
538 |
path = ""; // NOI18N |
539 |
base = targetName; |
540 |
} else { |
541 |
path = targetName.substring(0, idx); |
542 |
base = targetName.substring(idx + 1); |
543 |
} |
544 |
Element parent = otherfs.findElement(path); |
545 |
if (parent == null) throw new FileNotFoundException(path); |
546 |
el2.setAttribute("name", base); // NOI18N |
547 |
Element old = otherfs.findElement(targetName); |
548 |
if (el != el2) { |
549 |
// Cross-document import, so need to remove old one. |
550 |
el.getParentNode().removeChild(el); |
551 |
} |
552 |
if (old != null) { |
553 |
parent.replaceChild(el2, old); |
554 |
} else { |
555 |
appendWithIndent(parent, el2); |
556 |
} |
557 |
return true; |
558 |
} |
559 |
*/ |
560 |
|
561 |
public Enumeration<String> attributes(String name) { |
562 |
TreeElement el = findElement(name); |
563 |
if (el == null) { |
441 |
if (el == null) { |
564 |
return Enumerations.empty(); |
442 |
return Enumerations.empty(); |
565 |
} |
443 |
} |
566 |
java.util.List<String> l = new ArrayList<String>(10); |
444 |
java.util.List<String> l = new ArrayList<String>(10); |
567 |
Iterator it = el.getChildNodes(TreeElement.class).iterator(); |
445 |
for (Element sub : XMLUtil.findSubElements(el)) { |
568 |
while (it.hasNext()) { |
446 |
if (sub.getTagName().equals("attr")) { // NOI18N |
569 |
TreeElement sub = (TreeElement) it.next(); |
447 |
String nameAttr = sub.getAttribute("name"); // NOI18N |
570 |
if (sub.getLocalName().equals("attr")) { // NOI18N |
448 |
if (nameAttr.isEmpty()) { |
571 |
TreeAttribute nameAttr = sub.getAttribute("name"); // NOI18N |
|
|
572 |
if (nameAttr == null) { |
573 |
// Malformed. |
449 |
// Malformed. |
574 |
continue; |
450 |
continue; |
575 |
} |
451 |
} |
576 |
l.add(nameAttr.getValue()); |
452 |
l.add(nameAttr); |
577 |
} |
453 |
} |
578 |
} |
454 |
} |
579 |
return Collections.enumeration(l); |
455 |
return Collections.enumeration(l); |
580 |
} |
456 |
} |
581 |
|
457 |
|
582 |
public Object readAttribute(String name, String attrName) { |
458 |
public @Override Object readAttribute(String name, String attrName) { |
583 |
if (attrName.equals("WritableXMLFileSystem.cp")) { // NOI18N |
459 |
if (attrName.equals("WritableXMLFileSystem.cp")) { // NOI18N |
584 |
// XXX currently unused |
460 |
// XXX currently unused |
585 |
return classpath; |
461 |
return classpath; |
Lines 589-597
Link Here
|
589 |
return new URL[] {location}; |
465 |
return new URL[] {location}; |
590 |
} |
466 |
} |
591 |
if (attrName.equals("DataFolder.Index.reorderable")) { // NOI18N |
467 |
if (attrName.equals("DataFolder.Index.reorderable")) { // NOI18N |
592 |
return Boolean.TRUE; |
468 |
return true; // XXX is this still needed? |
593 |
} |
469 |
} |
594 |
TreeElement el = findElement(name); |
470 |
Element el = findElement(name); |
595 |
if (el == null) { |
471 |
if (el == null) { |
596 |
return null; |
472 |
return null; |
597 |
} |
473 |
} |
Lines 600-628
Link Here
|
600 |
attrName = attrName.substring("literal:".length()); // NOI18N |
476 |
attrName = attrName.substring("literal:".length()); // NOI18N |
601 |
literal = true; |
477 |
literal = true; |
602 |
} |
478 |
} |
603 |
Iterator it = el.getChildNodes(TreeElement.class).iterator(); |
479 |
for (Element sub : XMLUtil.findSubElements(el)) { |
604 |
while (it.hasNext()) { |
480 |
if (!sub.getTagName().equals("attr")) { // NOI18N |
605 |
TreeElement sub = (TreeElement) it.next(); |
|
|
606 |
if (!sub.getLocalName().equals("attr")) { // NOI18N |
607 |
continue; |
481 |
continue; |
608 |
} |
482 |
} |
609 |
TreeAttribute nameAttr = sub.getAttribute("name"); // NOI18N |
483 |
if (!attrName.equals(sub.getAttribute("name"))) { // NOI18N |
610 |
if (nameAttr == null) { |
|
|
611 |
// Malformed. |
612 |
continue; |
613 |
} |
614 |
if (!attrName.equals(nameAttr.getValue())) { |
615 |
continue; |
484 |
continue; |
616 |
} |
485 |
} |
617 |
try { |
486 |
try { |
618 |
if ((nameAttr = sub.getAttribute("stringvalue")) != null) { // NOI18N |
487 |
String val = sub.getAttribute("stringvalue"); // NOI18N |
|
|
488 |
if (!val.isEmpty()) { |
619 |
// Stolen from XMLMapAttr, with tweaks: |
489 |
// Stolen from XMLMapAttr, with tweaks: |
620 |
String inStr = nameAttr.getValue(); |
490 |
StringBuilder outStr = new StringBuilder(val.length()); |
621 |
StringBuffer outStr = new StringBuffer(inStr.length()); |
491 |
for (int j = 0; j < val.length(); j++) { |
622 |
for (int j = 0; j < inStr.length(); j++) { |
492 |
char ch = val.charAt(j); |
623 |
char ch = inStr.charAt(j); |
493 |
if (ch == '\\' && val.charAt(j + 1) == 'u' && j + 5 < val.length()) { |
624 |
if (ch == '\\' && inStr.charAt(j + 1) == 'u' && j + 5 < inStr.length()) { |
494 |
String hex = val.substring(j + 2, j + 6); |
625 |
String hex = inStr.substring(j + 2, j + 6); |
|
|
626 |
try { |
495 |
try { |
627 |
outStr.append((char) Integer.parseInt(hex, 16)); |
496 |
outStr.append((char) Integer.parseInt(hex, 16)); |
628 |
j += 5; |
497 |
j += 5; |
Lines 635-670
Link Here
|
635 |
} |
504 |
} |
636 |
} |
505 |
} |
637 |
return outStr.toString(); |
506 |
return outStr.toString(); |
638 |
} else if ((nameAttr = sub.getAttribute("boolvalue")) != null) { // NOI18N |
507 |
} else if (!(val = sub.getAttribute("boolvalue")).isEmpty()) { // NOI18N |
639 |
return Boolean.valueOf(nameAttr.getValue()); |
508 |
return Boolean.valueOf(val); |
640 |
} else if ((nameAttr = sub.getAttribute("urlvalue")) != null) { // NOI18N |
509 |
} else if (!(val = sub.getAttribute("urlvalue")).isEmpty()) { // NOI18N |
641 |
return new URL(nameAttr.getValue()); |
510 |
return new URL(val); |
642 |
} else if ((nameAttr = sub.getAttribute("charvalue")) != null) { // NOI18N |
511 |
} else if (!(val = sub.getAttribute("charvalue")).isEmpty()) { // NOI18N |
643 |
return new Character(nameAttr.getValue().charAt(0)); |
512 |
return Character.valueOf(val.charAt(0)); |
644 |
} else if ((nameAttr = sub.getAttribute("bytevalue")) != null) { // NOI18N |
513 |
} else if (!(val = sub.getAttribute("bytevalue")).isEmpty()) { // NOI18N |
645 |
return Byte.valueOf(nameAttr.getValue()); |
514 |
return Byte.valueOf(val); |
646 |
} else if ((nameAttr = sub.getAttribute("shortvalue")) != null) { // NOI18N |
515 |
} else if (!(val = sub.getAttribute("shortvalue")).isEmpty()) { // NOI18N |
647 |
return Short.valueOf(nameAttr.getValue()); |
516 |
return Short.valueOf(val); |
648 |
} else if ((nameAttr = sub.getAttribute("intvalue")) != null) { // NOI18N |
517 |
} else if (!(val = sub.getAttribute("intvalue")).isEmpty()) { // NOI18N |
649 |
return Integer.valueOf(nameAttr.getValue()); |
518 |
return Integer.valueOf(val); |
650 |
} else if ((nameAttr = sub.getAttribute("longvalue")) != null) { // NOI18N |
519 |
} else if (!(val = sub.getAttribute("longvalue")).isEmpty()) { // NOI18N |
651 |
return Long.valueOf(nameAttr.getValue()); |
520 |
return Long.valueOf(val); |
652 |
} else if ((nameAttr = sub.getAttribute("floatvalue")) != null) { // NOI18N |
521 |
} else if (!(val = sub.getAttribute("floatvalue")).isEmpty()) { // NOI18N |
653 |
return Float.valueOf(nameAttr.getValue()); |
522 |
return Float.valueOf(val); |
654 |
} else if ((nameAttr = sub.getAttribute("doublevalue")) != null) { // NOI18N |
523 |
} else if (!(val = sub.getAttribute("doublevalue")).isEmpty()) { // NOI18N |
655 |
return Double.valueOf(nameAttr.getValue()); |
524 |
return Double.valueOf(val); |
656 |
} else if ((nameAttr = sub.getAttribute("newvalue")) != null) { // NOI18N |
525 |
} else if (!(val = sub.getAttribute("newvalue")).isEmpty()) { // NOI18N |
657 |
String clazz = nameAttr.getValue(); |
526 |
String clazz = val; |
658 |
if (literal) { |
527 |
if (literal) { |
659 |
return "new:" + clazz; // NOI18N |
528 |
return "new:" + clazz; // NOI18N |
660 |
} // else XXX |
529 |
} // else XXX |
661 |
} else if ((nameAttr = sub.getAttribute("methodvalue")) != null) { // NOI18N |
530 |
} else if (!(val = sub.getAttribute("methodvalue")).isEmpty()) { // NOI18N |
662 |
String clazz = nameAttr.getValue(); |
531 |
String clazz = val; |
663 |
if (literal) { |
532 |
if (literal) { |
664 |
return "method:" + clazz; // NOI18N |
533 |
return "method:" + clazz; // NOI18N |
665 |
} // else XXX |
534 |
} // else XXX |
666 |
} else if ((nameAttr = sub.getAttribute("bundlevalue")) != null) { // NOI18N |
535 |
} else if (!(val = sub.getAttribute("bundlevalue")).isEmpty()) { // NOI18N |
667 |
String bundle = nameAttr.getValue(); |
536 |
String bundle = val; |
668 |
if (literal) { |
537 |
if (literal) { |
669 |
return "bundle:" + bundle; // NOI18N |
538 |
return "bundle:" + bundle; // NOI18N |
670 |
} else { |
539 |
} else { |
Lines 680-701
Link Here
|
680 |
} |
549 |
} |
681 |
return null; |
550 |
return null; |
682 |
/* |
551 |
/* |
683 |
if ((v = sub.getAttributeNode("bytevalue")) != null) { // NOI18N |
|
|
684 |
return new Byte(v.getValue()); |
685 |
} else if ((v = sub.getAttributeNode("shortvalue")) != null) { // NOI18N |
686 |
return new Short(v.getValue()); |
687 |
} else if ((v = sub.getAttributeNode("intvalue")) != null) { // NOI18N |
688 |
return new Integer(v.getValue()); |
689 |
} else if ((v = sub.getAttributeNode("longvalue")) != null) { // NOI18N |
690 |
return new Long(v.getValue()); |
691 |
} else if ((v = sub.getAttributeNode("floatvalue")) != null) { // NOI18N |
692 |
return new Float(v.getValue()); |
693 |
} else if ((v = sub.getAttributeNode("doublevalue")) != null) { // NOI18N |
694 |
// When was the last time you set a file attribute to a double?! |
695 |
// Useless list of primitives... |
696 |
return new Double(v.getValue()); |
697 |
} else if ((v = sub.getAttributeNode("charvalue")) != null) { // NOI18N |
698 |
return new Character(v.getValue().charAt(0)); |
699 |
} else if ((v = sub.getAttributeNode("methodvalue")) != null) { // NOI18N |
552 |
} else if ((v = sub.getAttributeNode("methodvalue")) != null) { // NOI18N |
700 |
String value = v.getValue(); |
553 |
String value = v.getValue(); |
701 |
Object[] params = new Object[] { findResource(name), attrName }; |
554 |
Object[] params = new Object[] { findResource(name), attrName }; |
Lines 812-924
Link Here
|
812 |
*/ |
665 |
*/ |
813 |
} |
666 |
} |
814 |
|
667 |
|
815 |
public void writeAttribute(String name, String attrName, Object v) throws IOException { |
668 |
public @Override void writeAttribute(String name, String attrName, Object v) throws IOException { |
816 |
//System.err.println("wA: " + name + " " + attrName + " " + v); |
669 |
//System.err.println("wA: " + name + " " + attrName + " " + v); |
817 |
if (v != null && v.getClass().getName().equals("org.openide.filesystems.MultiFileObject$VoidValue")) { // NOI18N |
670 |
if (v != null && v.getClass().getName().equals("org.openide.filesystems.MultiFileObject$VoidValue")) { // NOI18N |
818 |
// XXX is this legitimate? Definitely not pretty. But needed for testOpenideFolderOrder to pass. |
671 |
// XXX is this legitimate? Definitely not pretty. But needed for testOpenideFolderOrder to pass. |
819 |
v = null; |
672 |
v = null; |
820 |
} |
673 |
} |
821 |
TreeElement el = findElement(name); |
674 |
Element el = findElement(name); |
822 |
if (el == null) { |
675 |
if (el == null) { |
823 |
throw new FileNotFoundException(name); |
676 |
throw new FileNotFoundException(name); |
824 |
} |
677 |
} |
825 |
// Find any existing <attr>. |
678 |
// Find any existing <attr>. |
826 |
TreeChild existingAttr = null; |
679 |
Element existingAttr = null; |
827 |
Iterator it = el.getChildNodes(TreeElement.class).iterator(); |
680 |
for (Element sub : XMLUtil.findSubElements(el)) { |
828 |
while (it.hasNext()) { |
681 |
if (sub.getTagName().equals("attr") && sub.getAttribute("name").equals(attrName)) { // NOI18N |
829 |
TreeElement sub = (TreeElement) it.next(); |
682 |
existingAttr = sub; |
830 |
if (sub.getLocalName().equals("attr")) { // NOI18N |
683 |
break; |
831 |
TreeAttribute attr = sub.getAttribute("name"); // NOI18N |
|
|
832 |
if (attr == null) { |
833 |
// Malformed. |
834 |
continue; |
835 |
} |
836 |
if (attr.getValue().equals(attrName)) { |
837 |
existingAttr = sub; |
838 |
break; |
839 |
} |
840 |
} |
684 |
} |
841 |
} |
685 |
} |
842 |
TreeElement attr; |
686 |
Element attrE = el.getOwnerDocument().createElement("attr"); // NOI18N |
843 |
try { |
687 |
attrE.setAttribute("name", attrName); // NOI18N |
844 |
attr = new TreeElement("attr", true); // NOI18N |
688 |
if (v instanceof String) { |
845 |
attr.addAttribute("name", attrName); // NOI18N |
689 |
String inStr = (String) v; |
846 |
if (v instanceof String) { |
690 |
final String newValueMagic = "newvalue:"; // NOI18N |
847 |
String inStr = (String) v; |
691 |
final String methodValueMagic = "methodvalue:"; // NOI18N |
848 |
final String newValueMagic = "newvalue:"; // NOI18N |
692 |
final String bundleValueMagic = "bundlevalue:"; // NOI18N |
849 |
final String methodValueMagic = "methodvalue:"; // NOI18N |
693 |
if (inStr.startsWith(newValueMagic)) { |
850 |
final String bundleValueMagic = "bundlevalue:"; // NOI18N |
694 |
// Impossible to set this (reliably) as a real value, so use this magic technique instead: |
851 |
if (inStr.startsWith(newValueMagic)) { |
695 |
attrE.setAttribute("newvalue", inStr.substring(newValueMagic.length())); // NOI18N |
852 |
// Impossible to set this (reliably) as a real value, so use this magic technique instead: |
696 |
} else if (inStr.startsWith(methodValueMagic)) { |
853 |
attr.addAttribute("newvalue", inStr.substring(newValueMagic.length())); // NOI18N |
697 |
// Same here: |
854 |
} else if (inStr.startsWith(methodValueMagic)) { |
698 |
attrE.setAttribute("methodvalue", inStr.substring(methodValueMagic.length())); // NOI18N |
855 |
// Same here: |
699 |
} else if (inStr.startsWith(bundleValueMagic)) { |
856 |
attr.addAttribute("methodvalue", inStr.substring(methodValueMagic.length())); // NOI18N |
700 |
// Same here: |
857 |
} else if (inStr.startsWith(bundleValueMagic)) { |
701 |
attrE.setAttribute("bundlevalue", inStr.substring(bundleValueMagic.length())); // NOI18N |
858 |
// Same here: |
702 |
/* XXX figure out how to set DOCTYPE: |
859 |
attr.addAttribute("bundlevalue", inStr.substring(bundleValueMagic.length())); // NOI18N |
703 |
el.getOwnerDocument().getDoctype().setPublicId("-//NetBeans//DTD Filesystem 1.2//EN"); |
860 |
TreeObjectList nodes = doc.getChildNodes(); |
704 |
el.getOwnerDocument().getDoctype().setSystemId("http://www.netbeans.org/dtds/filesystem-1_2.dtd"); |
861 |
for (int i = 0; i < nodes.size(); i++) { |
705 |
*/ |
862 |
Object object = nodes.get(i); |
706 |
} else { |
863 |
if (object instanceof TreeDocumentType) { |
707 |
// Regular string value. |
864 |
TreeDocumentType tdt = (TreeDocumentType)object; |
708 |
// Stolen from XMLMapAttr w/ mods: |
865 |
tdt.setPublicId("-//NetBeans//DTD Filesystem 1.2//EN"); |
709 |
StringBuilder outStr = new StringBuilder(); |
866 |
tdt.setSystemId("http://www.netbeans.org/dtds/filesystem-1_2.dtd"); |
710 |
for (int i = 0; i < inStr.length(); i++) { |
867 |
break; |
711 |
char c = inStr.charAt(i); |
868 |
} |
712 |
if (Character.isISOControl(c) || c == '&' || c == '<' || c == '>' || c == '"' || c == '\'') { |
|
|
713 |
outStr.append(encodeChar(c)); |
714 |
} else { |
715 |
outStr.append(c); |
869 |
} |
716 |
} |
870 |
} else { |
|
|
871 |
// Regular string value. |
872 |
// Stolen from XMLMapAttr w/ mods: |
873 |
StringBuffer outStr = new StringBuffer(); |
874 |
for (int i = 0; i < inStr.length(); i++) { |
875 |
char c = inStr.charAt(i); |
876 |
if (Character.isISOControl(c) || c == '&' || c == '<' || c == '>' || c == '"' || c == '\'') { |
877 |
outStr.append(encodeChar(c)); |
878 |
} else { |
879 |
outStr.append(c); |
880 |
} |
881 |
} |
882 |
attr.addAttribute("stringvalue", outStr.toString()); // NOI18N |
883 |
} |
717 |
} |
884 |
} else if (v instanceof URL) { |
718 |
attrE.setAttribute("stringvalue", outStr.toString()); // NOI18N |
885 |
attr.addAttribute("urlvalue", ((URL) v).toExternalForm()); // NOI18N |
|
|
886 |
} else if (v instanceof Boolean) { |
887 |
attr.addAttribute("boolvalue", v.toString()); // NOI18N |
888 |
} else if (v instanceof Character) { |
889 |
attr.addAttribute("charvalue", v.toString()); // NOI18N |
890 |
} else if (v instanceof Integer) { |
891 |
attr.addAttribute("intvalue", v.toString()); // NOI18N |
892 |
} else if (v != null) { |
893 |
throw new UnsupportedOperationException("XXX: " + v); // NOI18N |
894 |
} |
719 |
} |
895 |
if (v != null && existingAttr == null) { |
720 |
} else if (v instanceof URL) { |
896 |
appendWithIndent(el, attr); |
721 |
attrE.setAttribute("urlvalue", ((URL) v).toExternalForm()); // NOI18N |
897 |
} else if (v != null) { |
722 |
} else if (v instanceof Boolean) { |
898 |
((TreeParentNode) el).replaceChild(existingAttr, attr); |
723 |
attrE.setAttribute("boolvalue", v.toString()); // NOI18N |
899 |
} else if (existingAttr != null) { |
724 |
} else if (v instanceof Character) { |
900 |
deleteWithIndent(existingAttr); |
725 |
attrE.setAttribute("charvalue", v.toString()); // NOI18N |
901 |
} |
726 |
} else if (v instanceof Integer) { |
902 |
} catch (InvalidArgumentException e) { |
727 |
attrE.setAttribute("intvalue", v.toString()); // NOI18N |
903 |
throw new AssertionError(e); |
728 |
} else if (v != null) { |
904 |
} catch (ReadOnlyException e) { |
729 |
throw new UnsupportedOperationException("XXX: " + v); // NOI18N |
905 |
throw (IOException) new IOException(e.toString()).initCause(e); |
730 |
} |
|
|
731 |
if (v != null && existingAttr == null) { |
732 |
model.insertBefore((org.netbeans.modules.xml.xdm.nodes.Node) el, |
733 |
(org.netbeans.modules.xml.xdm.nodes.Node) attrE, |
734 |
(org.netbeans.modules.xml.xdm.nodes.Node) findInsertionPosition(el, attrE)); |
735 |
} else if (v != null) { |
736 |
model.replaceChild((org.netbeans.modules.xml.xdm.nodes.Node) el, |
737 |
(org.netbeans.modules.xml.xdm.nodes.Node) attrE, |
738 |
(org.netbeans.modules.xml.xdm.nodes.Node) existingAttr); |
739 |
} else if (existingAttr != null) { |
740 |
model.removeChildNodes((org.netbeans.modules.xml.xdm.nodes.Node) el, |
741 |
Collections.singleton((org.netbeans.modules.xml.xdm.nodes.Node) existingAttr)); |
906 |
} |
742 |
} |
907 |
/* |
743 |
/* |
908 |
if (v instanceof Byte) { |
|
|
909 |
attr.setAttribute("bytevalue", v.toString()); // NOI18N |
910 |
} else if (v instanceof Short) { |
911 |
attr.setAttribute("shortvalue", v.toString()); // NOI18N |
912 |
} else if (v instanceof Integer) { |
913 |
attr.setAttribute("intvalue", v.toString()); // NOI18N |
914 |
} else if (v instanceof Long) { |
915 |
attr.setAttribute("longvalue", v.toString()); // NOI18N |
916 |
} else if (v instanceof Float) { |
917 |
attr.setAttribute("floatvalue", v.toString()); // NOI18N |
918 |
} else if (v instanceof Double) { |
919 |
attr.setAttribute("doublevalue", v.toString()); // NOI18N |
920 |
} else if (v instanceof Character) { |
921 |
attr.setAttribute("charvalue", v.toString()); // NOI18N |
922 |
} else { |
744 |
} else { |
923 |
// Stolen from XMLMapAttr, mostly. |
745 |
// Stolen from XMLMapAttr, mostly. |
924 |
ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
746 |
ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
Lines 1000-1022
Link Here
|
1000 |
return "\\u" + "0000".substring(0, "0000".length() - encChar.length()).concat(encChar); // NOI18N |
822 |
return "\\u" + "0000".substring(0, "0000".length() - encChar.length()).concat(encChar); // NOI18N |
1001 |
} |
823 |
} |
1002 |
|
824 |
|
1003 |
public void renameAttributes(String oldName, String newName) { |
825 |
public @Override void renameAttributes(String oldName, String newName) { |
1004 |
// do nothing |
826 |
// do nothing |
1005 |
} |
827 |
} |
1006 |
|
828 |
|
1007 |
public void deleteAttributes(String name) { |
829 |
public @Override void deleteAttributes(String name) { |
1008 |
// do nothing |
830 |
// do nothing |
1009 |
} |
831 |
} |
1010 |
|
832 |
|
1011 |
public boolean readOnly(String name) { |
833 |
public @Override boolean readOnly(String name) { |
1012 |
return false; |
834 |
return false; |
1013 |
} |
835 |
} |
1014 |
|
836 |
|
1015 |
public String mimeType(String name) { |
837 |
public @Override String mimeType(String name) { |
1016 |
return null; // i.e. use default resolvers |
838 |
return null; // i.e. use default resolvers |
1017 |
} |
839 |
} |
1018 |
|
840 |
|
1019 |
public long size(String name) { |
841 |
public @Override long size(String name) { |
1020 |
try { |
842 |
try { |
1021 |
return getContentsOf(name).length; |
843 |
return getContentsOf(name).length; |
1022 |
} catch (FileNotFoundException fnfe) { |
844 |
} catch (FileNotFoundException fnfe) { |
Lines 1024-1043
Link Here
|
1024 |
} |
846 |
} |
1025 |
} |
847 |
} |
1026 |
|
848 |
|
1027 |
public void markUnimportant(String name) { |
849 |
public @Override void markUnimportant(String name) { |
1028 |
// do nothing |
850 |
// do nothing |
1029 |
} |
851 |
} |
1030 |
|
852 |
|
1031 |
public Date lastModified(String name) { |
853 |
public @Override Date lastModified(String name) { |
1032 |
final TreeElement el = findElement(name); |
854 |
final Element el = findElement(name); |
1033 |
if (el == null) { |
855 |
if (el == null) { |
1034 |
return new Date(0L); |
856 |
return new Date(0L); |
1035 |
} |
857 |
} |
1036 |
TreeAttribute attr = el.getAttribute("url"); // NOI18N |
858 |
String u = el.getAttribute("url"); // NOI18N |
1037 |
if (attr == null) { |
859 |
if (u.isEmpty()) { |
1038 |
return new Date(0L); |
860 |
return new Date(0L); |
1039 |
} |
861 |
} |
1040 |
String u = attr.getValue(); |
|
|
1041 |
URI uri = null; |
862 |
URI uri = null; |
1042 |
try { |
863 |
try { |
1043 |
uri = new URI(null, u, null); |
864 |
uri = new URI(null, u, null); |
Lines 1063-1117
Link Here
|
1063 |
|
884 |
|
1064 |
// These are not important for us: |
885 |
// These are not important for us: |
1065 |
|
886 |
|
1066 |
public void lock(String name) throws IOException { |
887 |
public @Override void lock(String name) throws IOException { |
1067 |
// [PENDING] should this try to lock the XML document?? |
888 |
// [PENDING] should this try to lock the XML document?? |
1068 |
// (not clear if it is safe to do so from FS call, even tho |
889 |
// (not clear if it is safe to do so from FS call, even tho |
1069 |
// on a different FS) |
890 |
// on a different FS) |
1070 |
} |
891 |
} |
1071 |
|
892 |
|
1072 |
public void unlock(String name) { |
893 |
public @Override void unlock(String name) { |
1073 |
// do nothing |
894 |
// do nothing |
1074 |
} |
895 |
} |
1075 |
|
896 |
|
1076 |
// don't bother making configurable; or could use an indentation engine |
|
|
1077 |
private static final int INDENT_STEP = 4; |
1078 |
/** |
1079 |
* Add a new element to a parent in the correct position. |
1080 |
* Inserts whitespace to retain indentation rules. |
1081 |
*/ |
1082 |
private static void appendWithIndent(TreeElement parent, TreeChild child) throws ReadOnlyException { |
1083 |
TreeParentNode doc = parent; |
1084 |
int depth = -2; // will get <filesystem> then TreeDocument then null |
1085 |
while (doc != null) { |
1086 |
doc = ((TreeChild) doc).getParentNode(); |
1087 |
depth++; |
1088 |
} |
1089 |
TreeChild position = insertBefore(parent, child); |
1090 |
try { |
1091 |
if (position != null) { |
1092 |
parent.insertBefore(child, position); |
1093 |
parent.insertBefore(new TreeText("\n" + spaces((depth + 1) * INDENT_STEP)), position); // NOI18N |
1094 |
} else { |
1095 |
if (/*XXX this is clumsy*/ parent.hasChildNodes()) { |
1096 |
parent.appendChild(new TreeText(spaces(INDENT_STEP))); |
1097 |
} else { |
1098 |
parent.appendChild(new TreeText("\n" + spaces((depth + 1) * INDENT_STEP))); // NOI18N |
1099 |
} |
1100 |
parent.appendChild(child); |
1101 |
parent.appendChild(new TreeText("\n" + spaces(depth * INDENT_STEP))); // NOI18N |
1102 |
} |
1103 |
parent.normalize(); |
1104 |
/* XXX could check for adding position attr and resort parent of parent? |
1105 |
TreeElement childe = (TreeElement) child; |
1106 |
if (childe.getQName().equals("attr") && childe.getAttribute("name").getValue().indexOf('/') != -1) { // NOI18N |
1107 |
// Check for ordering attributes, which we have to handle specially. |
1108 |
resort(parent); |
1109 |
} |
1110 |
*/ |
1111 |
} catch (InvalidArgumentException e) { |
1112 |
assert false : e; |
1113 |
} |
1114 |
} |
1115 |
/** |
897 |
/** |
1116 |
* Find the proper location for a newly inserted element. |
898 |
* Find the proper location for a newly inserted element. |
1117 |
* Rules: |
899 |
* Rules: |
Lines 1119-1387
Link Here
|
1119 |
* 2. <attr> must be added to top of element in alpha order w.r.t. existing ones. |
901 |
* 2. <attr> must be added to top of element in alpha order w.r.t. existing ones. |
1120 |
* Returns a position to insert before (null for end). |
902 |
* Returns a position to insert before (null for end). |
1121 |
*/ |
903 |
*/ |
1122 |
private static TreeChild insertBefore(TreeElement parent, TreeChild child) throws ReadOnlyException { |
904 |
private static Element findInsertionPosition(Element parent, Element child) { |
1123 |
if (!(child instanceof TreeElement)) { |
905 |
if (child.getTagName().equals("file") || child.getTagName().equals("folder")) { // NOI18N |
1124 |
return null; // TBD for now |
906 |
String name = child.getAttribute("name"); // NOI18N |
1125 |
} |
907 |
for (Element kid : XMLUtil.findSubElements(parent)) { |
1126 |
TreeElement childe = (TreeElement) child; |
908 |
if ((kid.getTagName().equals("file") || kid.getTagName().equals("folder")) && kid.getAttribute("name").compareTo(name) > 0) { // NOI18N |
1127 |
if (childe.getQName().equals("file") || childe.getQName().equals("folder")) { // NOI18N |
909 |
return kid; |
1128 |
String name = childe.getAttribute("name").getValue(); // NOI18N |
|
|
1129 |
Iterator it = parent.getChildNodes(TreeElement.class).iterator(); |
1130 |
while (it.hasNext()) { |
1131 |
TreeElement kid = (TreeElement) it.next(); |
1132 |
if (kid.getQName().equals("file") || kid.getQName().equals("folder")) { // NOI18N |
1133 |
TreeAttribute attr = kid.getAttribute("name"); // NOI18N |
1134 |
if (attr != null) { // #66816 - layer might be malformed |
1135 |
String kidname = attr.getValue(); |
1136 |
if (kidname.compareTo(name) > 0) { |
1137 |
return kid; |
1138 |
} |
1139 |
} |
1140 |
} |
910 |
} |
1141 |
} |
911 |
} |
1142 |
return null; |
912 |
return null; |
1143 |
} else if (childe.getQName().equals("attr")) { // NOI18N |
913 |
} else if (child.getTagName().equals("attr")) { // NOI18N |
1144 |
String name = childe.getAttribute("name").getValue(); // NOI18N |
914 |
String name = child.getAttribute("name"); // NOI18N |
1145 |
Iterator it = parent.getChildNodes(TreeElement.class).iterator(); |
915 |
for (Element kid : XMLUtil.findSubElements(parent)) { |
1146 |
while (it.hasNext()) { |
916 |
if (kid.getTagName().equals("file") || kid.getTagName().equals("folder")) { // NOI18N |
1147 |
TreeElement kid = (TreeElement) it.next(); |
|
|
1148 |
if (kid.getQName().equals("file") || kid.getQName().equals("folder")) { // NOI18N |
1149 |
return kid; |
917 |
return kid; |
1150 |
} else if (kid.getQName().equals("attr")) { // NOI18N |
918 |
} else if (kid.getTagName().equals("attr") && kid.getAttribute("name").compareTo(name) > 0) { // NOI18N |
1151 |
TreeAttribute attr = kid.getAttribute("name"); // NOI18N |
919 |
return kid; |
1152 |
if (attr != null) { |
|
|
1153 |
String kidname = attr.getValue(); |
1154 |
if (kidname.compareTo(name) > 0) { |
1155 |
return kid; |
1156 |
} |
1157 |
} |
1158 |
} else { |
1159 |
throw new AssertionError("Weird child: " + kid.getQName()); |
1160 |
} |
920 |
} |
1161 |
} |
921 |
} |
1162 |
return null; |
922 |
return null; |
1163 |
} else { |
923 |
} else { |
1164 |
throw new AssertionError("Weird child: " + childe.getQName()); |
924 |
throw new AssertionError("Weird child: " + child.getTagName()); |
1165 |
} |
925 |
} |
1166 |
} |
926 |
} |
1167 |
/** |
|
|
1168 |
* Resort all files and folders and attributes in a folder context. The order is: |
1169 |
* 1. Attributes are alpha-sorted at the top. |
1170 |
* 2. Files and folders are alpha-sorted if they have no position. |
1171 |
* 3. Files with positions are sorted numerically above files without. |
1172 |
*/ |
1173 |
/* XXX not important yet |
1174 |
private static void resort(TreeElement parent) throws ReadOnlyException { |
1175 |
class Item { |
1176 |
public TreeElement child; |
1177 |
boolean isAttr() { |
1178 |
return child.getQName().equals("attr"); // NOI18N |
1179 |
} |
1180 |
String getName() { |
1181 |
TreeAttribute attr = child.getAttribute("name"); // NOI18N |
1182 |
return attr != null ? attr.getValue() : ""; |
1183 |
} |
1184 |
boolean isOrderingAttr() { |
1185 |
return isAttr() && getName().indexOf('/') != -1; |
1186 |
} |
1187 |
String getFormer() { |
1188 |
String n = getName(); |
1189 |
return n.substring(0, n.indexOf('/')); |
1190 |
} |
1191 |
String getLatter() { |
1192 |
String n = getName(); |
1193 |
return n.substring(n.indexOf('/') + 1); |
1194 |
} |
1195 |
} |
1196 |
Set<Item> items = new LinkedHashSet(); |
1197 |
SortedSet<Integer> indices = new TreeSet(); |
1198 |
for (int i = 0; i < parent.getChildrenNumber(); i++) { |
1199 |
TreeChild child = (TreeChild) parent.getChildNodes().get(i); |
1200 |
if (child instanceof TreeElement) { |
1201 |
Item item = new Item(); |
1202 |
item.child = (TreeElement) child; |
1203 |
items.add(item); |
1204 |
indices.add(new Integer(i)); |
1205 |
} |
1206 |
} |
1207 |
Map<Item,Collection<Item>> edges = new LinkedHashMap(); |
1208 |
Map<String,Item> filesAndFolders = new LinkedHashMap(); |
1209 |
Map<String,Item> attrs = new LinkedHashMap(); |
1210 |
Set<String> orderedFilesAndFolders = new LinkedHashSet(); |
1211 |
Iterator it = items.iterator(); |
1212 |
while (it.hasNext()) { |
1213 |
Item item = (Item) it.next(); |
1214 |
String name = item.getName(); |
1215 |
if (item.isAttr()) { |
1216 |
attrs.put(name, item); |
1217 |
if (item.isOrderingAttr()) { |
1218 |
orderedFilesAndFolders.add(item.getFormer()); |
1219 |
orderedFilesAndFolders.add(item.getLatter()); |
1220 |
} |
1221 |
} else { |
1222 |
filesAndFolders.put(name, item); |
1223 |
} |
1224 |
} |
1225 |
class NameComparator implements Comparator { |
1226 |
public int compare(Object o1, Object o2) { |
1227 |
Item i1 = (Item) o1; |
1228 |
Item i2 = (Item) o2; |
1229 |
return i1.getName().compareTo(i2.getName()); |
1230 |
} |
1231 |
} |
1232 |
Set<Item> sortedAttrs = new TreeSet(new NameComparator()); |
1233 |
Set<Item> sortedFilesAndFolders = new TreeSet(new NameComparator()); |
1234 |
Set<Item> orderableItems = new LinkedHashSet(); |
1235 |
it = items.iterator(); |
1236 |
while (it.hasNext()) { |
1237 |
Item item = (Item) it.next(); |
1238 |
String name = item.getName(); |
1239 |
if (item.isAttr()) { |
1240 |
if (item.isOrderingAttr()) { |
1241 |
Item former = (Item) filesAndFolders.get(item.getFormer()); |
1242 |
if (former != null) { |
1243 |
Set<Item> formerConstraints = (Set) edges.get(former); |
1244 |
if (formerConstraints == null) { |
1245 |
formerConstraints = new LinkedHashSet(); |
1246 |
edges.put(former, formerConstraints); |
1247 |
} |
1248 |
formerConstraints.add(item); |
1249 |
} |
1250 |
Item latter = (Item) filesAndFolders.get(item.getLatter()); |
1251 |
if (latter != null) { |
1252 |
Set<Item> constraints = new LinkedHashSet(); |
1253 |
constraints.add(latter); |
1254 |
edges.put(item, constraints); |
1255 |
} |
1256 |
orderableItems.add(item); |
1257 |
} else { |
1258 |
sortedAttrs.add(item); |
1259 |
} |
1260 |
} else { |
1261 |
if (orderedFilesAndFolders.contains(name)) { |
1262 |
orderableItems.add(item); |
1263 |
} else { |
1264 |
sortedFilesAndFolders.add(item); |
1265 |
} |
1266 |
} |
1267 |
} |
1268 |
java.util.List<Item> orderedItems; |
1269 |
try { |
1270 |
orderedItems = Utilities.topologicalSort(orderableItems, edges); |
1271 |
} catch (TopologicalSortException e) { |
1272 |
// OK, ignore. |
1273 |
return; |
1274 |
} |
1275 |
it = items.iterator(); |
1276 |
while (it.hasNext()) { |
1277 |
Item item = (Item) it.next(); |
1278 |
parent.removeChild(item.child); |
1279 |
} |
1280 |
java.util.List<Item> allOrderedItems = new ArrayList(sortedAttrs); |
1281 |
allOrderedItems.addAll(orderedItems); |
1282 |
allOrderedItems.addAll(sortedFilesAndFolders); |
1283 |
assert new HashSet(allOrderedItems).equals(items); |
1284 |
it = allOrderedItems.iterator(); |
1285 |
Iterator indexIt = indices.iterator(); |
1286 |
while (it.hasNext()) { |
1287 |
Item item = (Item) it.next(); |
1288 |
int index = ((Integer) indexIt.next()).intValue(); |
1289 |
parent.insertChildAt(item.child, index); |
1290 |
} |
1291 |
} |
1292 |
*/ |
1293 |
private static String spaces(int size) { |
1294 |
char[] chars = new char[size]; |
1295 |
for (int i = 0; i < size; i++) { |
1296 |
chars[i] = ' '; |
1297 |
} |
1298 |
return new String(chars); |
1299 |
} |
1300 |
/** |
1301 |
* Remove an element (and its children), deleting any surrounding newlines and indentation too. |
1302 |
*/ |
1303 |
private static void deleteWithIndent(TreeChild child) throws ReadOnlyException { |
1304 |
TreeChild next = child.getNextSibling(); |
1305 |
// XXX better might be to delete any maximal [ \t]+ previous plus \n next (means splitting up TreeText's) |
1306 |
if (next instanceof TreeText && ((TreeText) next).getData().matches("(\r|\n|\r\n)[ \t]+")) { // NOI18N |
1307 |
next.removeFromContext(); |
1308 |
} else { |
1309 |
TreeChild previous = child.getPreviousSibling(); |
1310 |
if (previous instanceof TreeText && ((TreeText) previous).getData().matches("(\r|\n|\r\n)[ \t]+")) { // NOI18N |
1311 |
previous.removeFromContext(); |
1312 |
} else { |
1313 |
// Well, not sure what is here, so skip it. |
1314 |
} |
1315 |
} |
1316 |
TreeElement parent = (TreeElement) child.getParentNode(); |
1317 |
TreeObjectList list = parent.getChildNodes(); |
1318 |
boolean kill = true; |
1319 |
Iterator it = list.iterator(); |
1320 |
while (it.hasNext()) { |
1321 |
Object o = it.next(); |
1322 |
if (o == child) { |
1323 |
continue; |
1324 |
} |
1325 |
if (!(o instanceof TreeText)) { |
1326 |
kill = false; |
1327 |
break; |
1328 |
} |
1329 |
if (((TreeText) o).getData().trim().length() > 0) { |
1330 |
kill = false; |
1331 |
break; |
1332 |
} |
1333 |
} |
1334 |
if (kill) { |
1335 |
try { |
1336 |
// Special case for root of filesystem. |
1337 |
if (((TreeChild) parent).getParentNode() instanceof TreeDocumentRoot) { |
1338 |
it = list.iterator(); |
1339 |
while (it.hasNext()) { |
1340 |
((TreeChild) it.next()).removeFromContext(); |
1341 |
} |
1342 |
parent.appendChild(new TreeText("\n")); // NOI18N |
1343 |
} else { |
1344 |
// Make sure we convert it to an empty tag (seems to only affect elements |
1345 |
// which were originally parsed?): |
1346 |
TreeElement parent2 = new TreeElement(parent.getQName(), true); |
1347 |
TreeAttribute attr = parent.getAttribute("name"); // NOI18N |
1348 |
if (attr != null) { |
1349 |
parent2.addAttribute("name", attr.getValue()); // NOI18N |
1350 |
} |
1351 |
TreeParentNode grandparent = ((TreeChild) parent).getParentNode(); |
1352 |
// TreeElement.empty is sticky - cannot be changed retroactively (argh!). |
1353 |
grandparent.replaceChild(parent, parent2); |
1354 |
parent = parent2; // for normalize() below |
1355 |
} |
1356 |
} catch (InvalidArgumentException e) { |
1357 |
assert false : e; |
1358 |
} |
1359 |
} |
1360 |
child.removeFromContext(); |
1361 |
parent.normalize(); |
1362 |
} |
1363 |
|
927 |
|
1364 |
// Listen to changes in files used as url= external contents. If these change, |
928 |
// Listen to changes in files used as url= external contents. If these change, |
1365 |
// the filesystem needs to show something else. Properly we would |
929 |
// the filesystem needs to show something else. Properly we would |
1366 |
// keep track of *which* file changed and thus which of our resources |
930 |
// keep track of *which* file changed and thus which of our resources |
1367 |
// is affected. Practically this would be a lot of work and gain |
931 |
// is affected. Practically this would be a lot of work and gain |
1368 |
// very little. |
932 |
// very little. |
1369 |
public void fileDeleted(FileEvent fe) { |
933 |
public @Override void fileDeleted(FileEvent fe) { |
1370 |
someFileChange(); |
934 |
someFileChange(); |
1371 |
} |
935 |
} |
1372 |
public void fileFolderCreated(FileEvent fe) { |
936 |
public @Override void fileFolderCreated(FileEvent fe) { |
1373 |
// does not apply to us |
937 |
// does not apply to us |
1374 |
} |
938 |
} |
1375 |
public void fileDataCreated(FileEvent fe) { |
939 |
public @Override void fileDataCreated(FileEvent fe) { |
1376 |
// not interesting here |
940 |
// not interesting here |
1377 |
} |
941 |
} |
1378 |
public void fileAttributeChanged(FileAttributeEvent fe) { |
942 |
public @Override void fileAttributeChanged(FileAttributeEvent fe) { |
1379 |
// don't care about attributes on included files... |
943 |
// don't care about attributes on included files... |
1380 |
} |
944 |
} |
1381 |
public void fileRenamed(FileRenameEvent fe) { |
945 |
public @Override void fileRenamed(FileRenameEvent fe) { |
1382 |
someFileChange(); |
946 |
someFileChange(); |
1383 |
} |
947 |
} |
1384 |
public void fileChanged(FileEvent fe) { |
948 |
public @Override void fileChanged(FileEvent fe) { |
1385 |
someFileChange(); |
949 |
someFileChange(); |
1386 |
} |
950 |
} |
1387 |
private void someFileChange() { |
951 |
private void someFileChange() { |
Lines 1389-1402
Link Here
|
1389 |
refreshResource("", true); |
953 |
refreshResource("", true); |
1390 |
} |
954 |
} |
1391 |
|
955 |
|
1392 |
public void propertyChange(PropertyChangeEvent evt) { |
956 |
public @Override void propertyChange(PropertyChangeEvent evt) { |
1393 |
if (!evt.getPropertyName().equals(TreeEditorCookie.PROP_DOCUMENT_ROOT)) { |
957 |
/* XXX do we need to synch periodically? |
1394 |
return; |
958 |
model.sync(); |
1395 |
} |
959 |
*/ |
1396 |
if (cookie.getStatus() == TreeEditorCookie.STATUS_OK || cookie.getStatus() == TreeEditorCookie.STATUS_NOT) { |
960 |
model.flush(); |
|
|
961 |
// XXX if supporting external changes: |
962 |
if (false/*model.getStatus() == XDMModel.Status.STABLE*/) { |
1397 |
// Document was modified, and reparsed OK. See what changed. |
963 |
// Document was modified, and reparsed OK. See what changed. |
1398 |
try { |
|
|
1399 |
doc = cookie.openDocumentRoot(); |
1400 |
/* Neither of the following work: |
964 |
/* Neither of the following work: |
1401 |
refreshResource("", true); // only works on root folder |
965 |
refreshResource("", true); // only works on root folder |
1402 |
refreshRoot(); // seems to do nothing at all |
966 |
refreshRoot(); // seems to do nothing at all |
Lines 1409-1419
Link Here
|
1409 |
} |
973 |
} |
1410 |
//System.err.println("got changes; new files: " + Collections.list(getRoot().getChildren(true))); |
974 |
//System.err.println("got changes; new files: " + Collections.list(getRoot().getChildren(true))); |
1411 |
//Thread.dumpStack(); |
975 |
//Thread.dumpStack(); |
1412 |
} catch (TreeException e) { |
|
|
1413 |
Util.err.notify(ErrorManager.INFORMATIONAL, e); |
1414 |
} catch (IOException e) { |
1415 |
Util.err.notify(ErrorManager.INFORMATIONAL, e); |
1416 |
} |
1417 |
} |
976 |
} |
1418 |
} |
977 |
} |
1419 |
|
978 |
|