KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > filesystems > DefaultAttributes


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.openide.filesystems;
21
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.BufferedOutputStream JavaDoc;
24 import java.io.Externalizable JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileNotFoundException JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.ObjectInput JavaDoc;
30 import java.io.ObjectInputStream JavaDoc;
31 import java.io.ObjectOutput JavaDoc;
32 import java.io.OutputStream JavaDoc;
33 import java.io.OutputStreamWriter JavaDoc;
34 import java.io.PrintWriter JavaDoc;
35 import java.io.PushbackInputStream JavaDoc;
36 import java.lang.ref.Reference JavaDoc;
37 import java.lang.ref.SoftReference JavaDoc;
38 import java.util.Collections JavaDoc;
39 import java.util.Enumeration JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.HashSet JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.Locale JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.util.TreeSet JavaDoc;
46 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
47 import javax.xml.parsers.ParserConfigurationException JavaDoc;
48 import org.openide.util.Enumerations;
49 import org.openide.util.NbBundle;
50 import org.openide.util.Utilities;
51 import org.openide.util.io.NbMarshalledObject;
52 import org.openide.xml.XMLUtil;
53 import org.xml.sax.Attributes JavaDoc;
54 import org.xml.sax.InputSource JavaDoc;
55 import org.xml.sax.SAXException JavaDoc;
56 import org.xml.sax.SAXParseException JavaDoc;
57 import org.xml.sax.XMLReader JavaDoc;
58 import org.xml.sax.helpers.DefaultHandler JavaDoc;
59
60 /** Implementation of <code>AbstractFileSystem.Attr</code> using a special file
61  * in each folder for holding attributes.
62  * It needs to hide
63  * the file from the rest of system, so it also implements
64  * <code>AbstractFileSystem.List</code> to exclude the file from the children list
65  * (it can then serve to filter a plain list implementation).
66  *
67  *Description of format of special file ilustrates best DTD file that is showed in next lines:
68  *<!ELEMENT attributes (fileobject)*>
69  * <!ATTLIST attributes version CDATA #REQUIRED>
70  * <!ELEMENT fileobject (attr)*>
71  * <!ATTLIST fileobject name CDATA #REQUIRED>
72  * <!ELEMENT attr EMPTY>
73  * <!ATTLIST attr name CDATA #REQUIRED>
74  * <!ATTLIST attr bytevalue CDATA #IMPLIED>
75  * <!ATTLIST attr shortvalue CDATA #IMPLIED>
76  * <!ATTLIST attr intvalue CDATA #IMPLIED>
77  * <!ATTLIST attr longvalue CDATA #IMPLIED>
78  * <!ATTLIST attr floatvalue CDATA #IMPLIED>
79  * <!ATTLIST attr doublevalue CDATA #IMPLIED>
80  * <!ATTLIST attr boolvalue CDATA #IMPLIED>
81  * <!ATTLIST attr charvalue CDATA #IMPLIED>
82  * <!ATTLIST attr stringvalue CDATA #IMPLIED>
83  * <!ATTLIST attr methodvalue CDATA #IMPLIED>
84  * <!ATTLIST attr serialvalue CDATA #IMPLIED>
85  * <!ATTLIST attr urlvalue CDATA #IMPLIED>
86  *
87  * @author Jaroslav Tulach
88  */

89 @SuppressWarnings JavaDoc("unchecked")
90 public class DefaultAttributes extends Object JavaDoc implements AbstractFileSystem.Attr, AbstractFileSystem.List {
91     static final long serialVersionUID = -5801291358293736478L;
92
93     /** File name of special file in each folder where attributes are saved.
94      * @deprecated does not handle XML attributes
95      */

96     @Deprecated JavaDoc
97     public final static String JavaDoc ATTR_NAME = "filesystem"; // NOI18N
98

99     /** Extension of special file in each folder where attributes are saved.
100      * @deprecated does not handle XML attributes
101      */

102     @Deprecated JavaDoc
103     public final static String JavaDoc ATTR_EXT = "attributes"; // NOI18N
104

105     /** Name with extension of special file in each folder where attributes are saved.
106      * @deprecated does not handle XML attributes
107      */

108     @Deprecated JavaDoc
109     public final static String JavaDoc ATTR_NAME_EXT = ATTR_NAME + '.' + ATTR_EXT;
110     private final static String JavaDoc ATTR_NAME_EXT_XML = System.getProperty(
111             "org.openide.filesystems.DefaultAttributes.ATTR_NAME_EXT_XML", ".nbattrs"
112         ); // NOI18N
113

114     /** readOnlyAttrs is name of virtual attribute. This name of virtual attribute
115      * is shared between classes (and cannot be changed without breaking compatibility):
116      * - org.openide.filesystems.DefaultAttributes
117      * - org.openide.loaders.ExecutionSupport
118      * - org.openide.loaders.CompilerSupport
119      * - org.netbeans.core.ExJarFileSystem
120      */

121     private final static String JavaDoc READONLY_ATTRIBUTES = "readOnlyAttrs"; //NOI18N
122

123     // <?xml version="1.0"?>
124
// <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD DefaultAttributes 1.0//EN" "http://www.netbeans.org/dtds/attributes-1_0.dtd">
125
// <attributes>...</attributes>
126
private static final String JavaDoc PUBLIC_ID = "-//NetBeans//DTD DefaultAttributes 1.0//EN"; // NOI18N
127
private static final String JavaDoc DTD_PATH = "org/openide/filesystems/attributes.dtd"; // NOI18N
128

129     /** description of the fs to work on - info about files */
130     private AbstractFileSystem.Info info;
131
132     /** description of the fs to work on - work with files */
133     private AbstractFileSystem.Change change;
134
135     /** description of the fs to work on - listing of files */
136     private AbstractFileSystem.List list;
137
138     /** file name of attributes (default value corresponds to ATTR_NAME_EXT_XML) */
139     private String JavaDoc fileName;
140
141     /** Cache of attributes.
142     * For name of folder gives map of maps of attibutes
143     * (String, Reference (Table))
144     */

145     private transient Map JavaDoc cache;
146
147     /** Constructor.
148     * @param info file object information to use
149     * @param change file change hooks to use
150     * @param list list to filter (can be <code>null</code>, but then this object cannot work as a list)
151     */

152     public DefaultAttributes(
153         AbstractFileSystem.Info info, AbstractFileSystem.Change change, AbstractFileSystem.List list
154     ) {
155         this.info = info;
156         this.change = change;
157         this.list = list;
158         fileName = ATTR_NAME_EXT_XML;
159     }
160
161     /** Constructor.
162      *
163      * @param info file object information to use
164      * @param change file change hooks to use
165      * @param list list to filter (can be <code>null</code>, but then this object cannot work as a list)
166      * @param fileName
167      * @since 4.35
168      */

169     protected DefaultAttributes(
170         AbstractFileSystem.Info info, AbstractFileSystem.Change change, AbstractFileSystem.List list, String JavaDoc fileName
171     ) {
172         this(info, change, list);
173         this.fileName = fileName;
174     }
175
176     /** Methods to ensure backward compatibility for storing and
177     * loading classes.
178     */

179     private void readObject(ObjectInputStream JavaDoc ois) throws ClassNotFoundException JavaDoc, IOException JavaDoc {
180         ObjectInputStream.GetField JavaDoc fields = ois.readFields();
181
182         Object JavaDoc o1 = AbstractFileSystem.readImpl("change", fields); // NOI18N
183
Object JavaDoc o2 = AbstractFileSystem.readImpl("info", fields); // NOI18N
184
Object JavaDoc o3 = AbstractFileSystem.readImpl("list", fields); // NOI18N
185

186         change = (AbstractFileSystem.Change) o1;
187         info = (AbstractFileSystem.Info) o2;
188         list = (AbstractFileSystem.List) o3;
189     }
190
191     /** Get the children list, filtering out the special attributes file.
192     * You <em>must</em> have provided a non-<code>null</code> {@link AbstractFileSystem.List}
193     * in the constructor for this to work. If you did not, the rest of the class will work
194     * fine, but this method should not be called and this object should not be used
195     * as a <code>List</code> implementation.
196     *
197     * @param f the folder, by name; e.g. <code>top/next/afterthat</code>
198     * @return a list of children of the folder, as <code>file.ext</code> (no path)
199     */

200     public String JavaDoc[] children(String JavaDoc f) {
201         String JavaDoc[] arr = list.children(f);
202         int lookUpIndex = 0;
203
204         if (arr == null) {
205             return null;
206         }
207
208         int size = arr.length;
209
210         if (size == 1) {
211             // In NB 3.2.x for OpenVMS, we had to use "_nbattrs." as a attribute file.
212
// However, OpenVMS now supports a file name beginning with "."
213
// So we now have to copy the existing "_nbattrs." file into ".nbattrs"
214
//
215
if ((Utilities.getOperatingSystem() == Utilities.OS_VMS) && (arr[0] != null) && (f != null)) {
216                 if (arr[0].equalsIgnoreCase("_nbattrs.")) {
217                     try {
218                         deleteFile(f + "/" + arr[0]); // NOI18N
219
} catch (IOException JavaDoc ioe) {
220                     }
221
222                     arr[0] = getFileName();
223                 }
224             }
225
226             if ((getFileName().equals(arr[0]) || ATTR_NAME_EXT_XML.equals(arr[0]) || ATTR_NAME_EXT.equals(arr[0]))) {
227                 try {
228                     deleteFile(f + "/" + arr[0]); // NOI18N
229
} catch (IOException JavaDoc iox) {
230                 }
231
232                 return new String JavaDoc[] { };
233             }
234         }
235
236         for (int i = 0; i < size; i++) {
237             // In NB 3.2.x for OpenVMS, we had to use "_nbattrs." as a attribute file.
238
// However, OpenVMS now supports a file name beginning with "."
239
// So we now have to copy the existing "_nbattrs." file into ".nbattrs"
240
//
241
if ((Utilities.getOperatingSystem() == Utilities.OS_VMS) && (arr[i] != null) && (f != null)) {
242                 if (arr[i].equalsIgnoreCase("_nbattrs.")) {
243                     try {
244                         File JavaDoc fp = new File JavaDoc(f + "/" + ".nbattrs");
245
246                         if (!fp.exists()) {
247                             cache = null;
248                             copyVMSAttrFile(f);
249                         }
250                     } catch (IOException JavaDoc ioe) {
251                     }
252
253                     arr[i] = getFileName();
254                 }
255             }
256
257             String JavaDoc safeNbAttrsCopy = getFileName() + "~"; //NOI18N
258

259             if (
260                 getFileName().equals(arr[i]) || ATTR_NAME_EXT.equals(arr[i]) || ATTR_NAME_EXT_XML.equals(arr[i]) ||
261                     safeNbAttrsCopy.equals(arr[i])
262             ) {
263                 // exclude this index
264
arr[i] = null;
265
266                 // there can be two files with attributes
267
if (++lookUpIndex >= 2) {
268                     break;
269                 }
270             }
271         }
272
273         return arr;
274     }
275
276     /** Renames the attribute file for OpenVMS platform.
277      * The method renames "_nbattrs." into ".nbattrs".
278      * We cannot simply use the change.rename method
279      * because of the special property of OpenVMS having to do with
280      * a file name starting with "."
281      *
282      * @param f the folder containg the attribute file
283      */

284     private void copyVMSAttrFile(String JavaDoc f) throws IOException JavaDoc {
285         InputStream JavaDoc is = null;
286         OutputStream JavaDoc os = null;
287
288         try {
289             change.createData(f + "/" + getFileName());
290             is = info.inputStream(f + "/" + "_nbattrs.");
291             os = info.outputStream(f + "/" + getFileName());
292
293             byte[] buf = new byte[256];
294             int readi;
295
296             while ((readi = is.read(buf, 0, 256)) >= 0x0) {
297                 os.write(buf, 0, readi);
298             }
299
300             is.close();
301
302             //change.delete (f+"/"+"_nbattrs.");
303
is = null;
304         } catch (IOException JavaDoc ie) {
305         } finally {
306             if (is != null) {
307                 is.close();
308             }
309
310             if (os != null) {
311                 os.close();
312             }
313         }
314     }
315
316     // JST: Description
317
//
318
//
319
// The class should be written in such a way that the access to disk is
320
// synchronized (this). But during the access nobody is allowed to
321
// perform serialization and deserialization
322
// of unknown objects, so all objects should be wrapped into NbMarshalledObject
323
// serialized or in reverse target NbMarshalledObject should be deserialized
324
// and then not holding the lock the object obtained from it by a call to
325
// marshall.get ().
326
//
327
// JST: Got it?
328

329     /* Get the file attribute with the specified name.
330     * @param name the file
331     * @param attrName name of the attribute
332     * @return appropriate (serializable) value or <CODE>null</CODE> if the attribute is unset (or could not be properly restored for some reason)
333     */

334     public Object JavaDoc readAttribute(String JavaDoc name, String JavaDoc attrName) {
335         Table t;
336         String JavaDoc[] arr = new String JavaDoc[2];
337         split(name, arr);
338
339         /** At the momement substitutes lack of API */
340         if (attrName.equals(READONLY_ATTRIBUTES)) {
341             return info.readOnly(arr[0]) ? Boolean.TRUE : Boolean.FALSE;
342         }
343
344         synchronized (this) {
345             // synchronized so only one table for each folder
346
// can exist
347
t = loadTable(arr[0]);
348         }
349
350         // JST:
351
// had to split the code to do getAttr out of synchronized block
352
// because the attribute can be serialized FileObject and
353
// so the code returns back to FileSystem (that is usually synchronized)
354
//
355
// this leads to deadlocks between FS & DefaultAttributes implementation
356
//
357
// I do not know if the table should not be somehow synchronized,
358
// but it seems ok.
359
return t.getAttr(arr[1], attrName);
360     }
361
362     /* Set the file attribute with the specified name.
363     * @param name the file
364     * @param attrName name of the attribute
365     * @param value new value or <code>null</code> to clear the attribute. Must be serializable, although particular filesystems may or may not use serialization to store attribute values.
366     * @exception IOException if the attribute cannot be set. If serialization is used to store it, this may in fact be a subclass such as {@link NotSerializableException}.
367     */

368     public void writeAttribute(String JavaDoc name, String JavaDoc attrName, Object JavaDoc value)
369     throws IOException JavaDoc {
370         // create object that should be serialized
371
//NbMarshalledObject marshall = new NbMarshalledObject (value);
372
int objType;
373
374         String JavaDoc[] arr = new String JavaDoc[2];
375         split(name, arr);
376
377         for (;;) {
378             int version;
379             Table t;
380
381             synchronized (this) {
382                 t = loadTable(arr[0]);
383                 version = t.version;
384             }
385
386             // Tests if the attribute is changing
387
Object JavaDoc prev = t.getAttr(arr[1], attrName);
388
389             if (prev == value /*|| (value != null && value.equals (prev))*/ ) {
390                 return;
391             }
392
393             synchronized (this) {
394                 Table t2 = loadTable(arr[0]);
395
396                 if ((t == t2) && (version == t2.version)) {
397                     // no modification between reading of the value =>
398
// save!
399
//Class cls = value.getClass();
400
if (value == null) {
401                         t.setAttr(arr[1], attrName, null); // clear the attribute
402
} else {
403                         if (
404                             (objType = XMLMapAttr.Attr.distinguishObject(value)) == XMLMapAttr.Attr.isValid(
405                                     "SERIALVALUE"
406                                 )
407                         ) { // NOI18N
408
t.setAttr(arr[1], attrName, value); //change value instead of marshall
409
} else {
410                             t.setAttr(arr[1], attrName, XMLMapAttr.createAttribute(objType, value.toString()));
411                         }
412                     }
413
414                     saveTable(arr[0], t);
415
416                     // ok, saved
417
return;
418                 }
419             }
420
421             // otherwise try it again
422
}
423     }
424
425     /* Get all file attribute names for the file.
426     * @param name the file
427     * @return enumeration of keys (as strings)
428     */

429     public synchronized Enumeration JavaDoc<String JavaDoc> attributes(String JavaDoc name) {
430         String JavaDoc[] arr = new String JavaDoc[2];
431         split(name, arr);
432
433         Table t = loadTable(arr[0]);
434
435         return t.attrs(arr[1]);
436     }
437
438     /* Called when a file is renamed, to appropriatelly update its attributes.
439     * <p>
440     * @param oldName old name of the file
441     * @param newName new name of the file
442     */

443     public synchronized void renameAttributes(String JavaDoc oldName, String JavaDoc newName) {
444         try {
445             String JavaDoc[] arr = new String JavaDoc[2];
446             split(oldName, arr);
447
448             Table t = loadTable(arr[0]);
449             Map JavaDoc v = (Map JavaDoc) t.remove(arr[1]);
450
451             // System.out.println ("ARg[0] = " + arr[0] + " arr[1] = " + arr[1] + " value: " + v); // NOI18N
452
if (v == null) {
453                 // no attrs no change
454
return;
455             }
456
457             split(newName, arr);
458
459             // Remove transient attributes:
460
Iterator JavaDoc it = v.entrySet().iterator();
461
462             while (it.hasNext()) {
463                 Map.Entry JavaDoc pair = (Map.Entry JavaDoc) it.next();
464
465                 if (FileUtil.transientAttributes.contains(pair.getKey())) {
466                     it.remove();
467                 }
468             }
469             t.put(arr[1], v);
470
471             // System.out.println ("xyz[0] = " + arr[0] + " xyz[1] = " + arr[1] + " value: " + v); // NOI18N
472
saveTable(arr[0], t);
473         } catch (IOException JavaDoc e) {
474             ExternalUtil.exception(e);
475         }
476     }
477
478     /* Called when a file is deleted to also delete its attributes.
479     *
480     * @param name name of the file
481     */

482     public synchronized void deleteAttributes(String JavaDoc name) {
483         try {
484             String JavaDoc[] arr = new String JavaDoc[2];
485             split(name, arr);
486
487             Table t = loadTable(arr[0]);
488
489             if (t.remove(arr[1]) != null) {
490                 // if there is a change
491
saveTable(arr[0], t);
492             }
493         } catch (IOException JavaDoc e) {
494             ExternalUtil.exception(e);
495         }
496     }
497
498     /** Getter for the cache.
499     */

500     private Map JavaDoc getCache() {
501         if (cache == null) {
502             cache = new HashMap JavaDoc(31);
503         }
504
505         return cache;
506     }
507
508     /** Splits name of a file to name of folder and to name of the file.
509     * @param name of file
510     * @param arr arr[0] will hold name of folder and arr[1] name of the file
511     */

512     private static void split(String JavaDoc name, String JavaDoc[] arr) {
513         int i = name.lastIndexOf('/');
514
515         if (i == -1) {
516             arr[0] = ""; // NOI18N
517
arr[1] = name;
518
519             return;
520         }
521
522         // folder name
523
arr[0] = name.substring(0, i);
524
525         // increase the i to be beyond the length
526
if (++i == name.length()) {
527             arr[1] = ""; // NOI18N
528
} else {
529             // split it
530
arr[1] = name.substring(i);
531         }
532     }
533
534     /** Save attributes.
535     * @param name name of folder to save attributes for
536     * @param map map to save
537     */

538     private void saveTable(String JavaDoc name, Table map) throws IOException JavaDoc {
539         String JavaDoc fullName = ((name.length() == 0) ? "" : (name + '/')) + getFileName(); // NOI18N
540

541         /** OpenVMS now supports various special characters including "~"*/
542         String JavaDoc safeName = fullName + "~"; // NOI18N
543

544         if (info.folder(fullName)) {
545             if (map.size() == 0) {
546                 // ok no need to delete
547
return;
548             }
549
550             // find parent
551
change.createData(fullName);
552         } else {
553             if (map.size() == 0) {
554                 deleteFile(fullName);
555
556                 return;
557             }
558         }
559
560         PrintWriter JavaDoc pw = null;
561         IOException JavaDoc ioexc = null;
562
563         try {
564             pw = new PrintWriter JavaDoc(new OutputStreamWriter JavaDoc(new BufferedOutputStream JavaDoc(info.outputStream(safeName)), "UTF8")); // NOI18N
565
map.writeToXML(pw);
566             pw.flush();
567         } catch (IOException JavaDoc iex) {
568             ioexc = iex;
569         } finally {
570             if (pw != null) {
571                 pw.close();
572             }
573
574             if (ioexc != null) {
575                 deleteFile(safeName);
576                 throw ioexc;
577             } else {
578                 try {
579                     deleteFile(fullName);
580                 } catch (IOException JavaDoc iex2) {
581                     /** if delete fails, then also rename fails and exception will
582                      * be fired
583                      */

584                 }
585
586                 this.change.rename(safeName, fullName);
587             }
588         }
589     }
590
591     /** Load attributes from cache or
592     * from disk.
593     * @param name of folder to load data from
594     */

595     private Table loadTable(String JavaDoc name) { //throws IOException {
596

597         Reference JavaDoc r = (Reference JavaDoc) getCache().get(name);
598
599         if (r != null) {
600             Table m = (Table) r.get();
601
602             if (m != null) {
603                 return m;
604             }
605         }
606
607         // have to load new table
608
Table t = load(name);
609         t.attach(name, this);
610
611         getCache().put(name, new SoftReference JavaDoc(t));
612
613         return t;
614     }
615
616     /** Loads the table. Does no initialization.
617     */

618     private Table load(String JavaDoc name) {
619         String JavaDoc[] acceptNames = {
620             ((name.length() == 0) ? "" : (name + '/')) + getFileName(), // NOI18N
621
((name.length() == 0) ? "" : (name + '/')) + ATTR_NAME_EXT
622         }; // NOI18N
623

624         for (int i = 0; i < acceptNames.length; i++) {
625             if (info.size(acceptNames[i]) > 0L) {
626                 try {
627                     InputStream JavaDoc fis = info.inputStream(acceptNames[i]);
628
629                     try {
630                         return loadTable(fis, acceptNames[i]);
631                     } finally {
632                         try {
633                             fis.close();
634                         } catch (IOException JavaDoc e) {
635                             // ignore--who cares?
636
}
637                     }
638                 } catch (FileNotFoundException JavaDoc ex) {
639                     ExternalUtil.exception(ex);
640                 }
641             }
642         }
643
644         return new Table();
645     }
646
647     /** Loads the Table of extended attributes for a input stream from binary serialized file or from XML.
648     * @param is input stream
649     * @param folderName name of file for better error message
650     * @return the attributes table for this input stream
651     */

652     static Table loadTable(InputStream JavaDoc is, String JavaDoc folderName) {
653         Table retTable = new Table();
654         PushbackInputStream JavaDoc pbStream = null;
655         boolean isSerialized = false;
656
657         try {
658             if (folderName.endsWith(ATTR_NAME_EXT)) {
659                 pbStream = new PushbackInputStream JavaDoc(is, 4); //is.available()
660
isSerialized = isSerialized(pbStream);
661             }
662
663             if (isSerialized && (pbStream != null)) {
664                 BufferedInputStream JavaDoc fis = new BufferedInputStream JavaDoc(pbStream);
665                 ObjectInputStream JavaDoc ois = new org.openide.util.io.NbObjectInputStream(fis);
666                 Object JavaDoc o = ois.readObject();
667
668                 if (o instanceof Table) {
669                     return (Table) o;
670                 }
671             } else {
672                 BufferedInputStream JavaDoc bis = (pbStream != null) ? new BufferedInputStream JavaDoc(pbStream)
673                                                              : new BufferedInputStream JavaDoc(is);
674                 retTable.readFromXML(bis, false);
675
676                 return retTable;
677             }
678         } catch (Exception JavaDoc e) {
679             // [PENDING] use multi-arg getMessage (MessageFormat-style) properly here:
680
IOException JavaDoc summaryEx = new IOException JavaDoc(
681                     NbBundle.getMessage(DefaultAttributes.class, "EXC_DefAttrReadErr") + ": " + folderName
682                 );
683             ExternalUtil.copyAnnotation(summaryEx, e);
684             ExternalUtil.exception(summaryEx);
685         }
686
687         // create empty table, what else
688
return new Table();
689     }
690
691     /** Tests whether InputStream contains serialized data
692     * @param pbStream is pushback input stream; tests 4 bytes and then returns them back
693     * @return true if the file has serialized form
694     */

695     static private final boolean isSerialized(PushbackInputStream JavaDoc pbStream)
696     throws IOException JavaDoc {
697         int[] serialPattern = { '\u00AC', '\u00ED', '\u0000', '\u0005' }; //NOI18N patern for serialized objects
698
byte[] checkedArray = new byte[serialPattern.length];
699         int unsignedConv = 0;
700
701         pbStream.read(checkedArray, 0, checkedArray.length);
702         pbStream.unread(checkedArray);
703
704         for (int i = 0; i < checkedArray.length; i++) {
705             unsignedConv = (checkedArray[i] < 0) ? (checkedArray[i] + 256) : checkedArray[i];
706
707             if (serialPattern[i] != unsignedConv) {
708                 return false;
709             }
710         }
711
712         return true;
713     }
714
715     /** Remove from cache */
716     synchronized void removeTable(String JavaDoc name) {
717         getCache().remove(name);
718     }
719
720     //
721
// FileUtil.extractJar methods
722
//
723

724     /** Does the name seems like file with extended attributes?
725     * @param name the name
726     * @return true if so
727     */

728     static boolean acceptName(String JavaDoc name) {
729         return (name.endsWith(ATTR_NAME_EXT) || name.endsWith(ATTR_NAME_EXT_XML));
730     }
731
732     private String JavaDoc getFileName() {
733         if (fileName == null) {
734             fileName = ATTR_NAME_EXT_XML;
735         }
736
737         return fileName;
738     }
739     
740     private void deleteFile(String JavaDoc name) throws IOException JavaDoc {
741         OutputStream JavaDoc os = null;
742         try {
743             this.info.lock(name);
744             //added because of mutual exclusion of streams (waits a while until stream is closed)
745
os = this.info.outputStream(name);
746             os.close(); os = null;
747             this.change.delete(name);
748         } finally {
749             if (os != null) {
750                 os.close();
751             }
752             this.info.unlock(name);
753         }
754     }
755     
756
757     /** Table that hold mapping between files and attributes.
758     * Hold mapping of type (String, Map (String, Object))
759     */

760     final static class Table extends HashMap JavaDoc implements Externalizable JavaDoc {
761         static final long serialVersionUID = 2353458763249746934L;
762
763         /** name of folder we belong to */
764         private transient String JavaDoc name;
765
766         /** attributes to belong to */
767         private transient DefaultAttributes attrs;
768
769         /** version counting */
770         private transient int version = 0;
771
772         /** Constructor */
773         public Table() {
774             super(11);
775         }
776
777         /** Attaches to file in attributes */
778         public void attach(String JavaDoc name, DefaultAttributes attrs) {
779             this.name = name;
780             this.attrs = attrs;
781         }
782
783         /** Remove itself from the cache if finalized.
784         */

785         protected void finalize() {
786             // System.out.println ("Finalizing table for: " + name); // NOI18N
787
attrs.removeTable(name);
788         }
789
790         /** For given file finds requested attribute.
791          * @param fileName name of the file
792          * @param attrName name of the attribute
793          * @return attribute or null (if not found)
794          */

795         public Object JavaDoc getAttr(String JavaDoc fileName, String JavaDoc attrName) {
796             XMLMapAttr m = (XMLMapAttr) get(fileName);
797
798             if (m != null) {
799                 Object JavaDoc o = null;
800
801                 try {
802                     o = m.getAttribute(attrName);
803                 } catch (Exception JavaDoc e) {
804                     ExternalUtil.annotate(e, "fileName = " + fileName); //NOI18N
805
ExternalUtil.exception(e);
806                 }
807
808                 if (o == null) {
809                     return null;
810                 }
811
812                 if (!(o instanceof NbMarshalledObject)) {
813                     return o;
814                 }
815
816                 NbMarshalledObject mo = (NbMarshalledObject) o;
817
818                 try {
819                     return (mo == null) ? null : mo.get();
820                 } catch (IOException JavaDoc e) {
821                     ExternalUtil.log("Cannot load attribute " + attrName + " from " + fileName); // NOI18N
822
ExternalUtil.exception(e);
823                 } catch (ClassNotFoundException JavaDoc e) {
824                     ExternalUtil.log("Cannot load attribute " + attrName + " from " + fileName); // NOI18N
825
ExternalUtil.exception(e);
826                 }
827             }
828
829             return null;
830         }
831
832         /** Sets an marshaled attribute to the table.
833         */

834         final void setMarshalledAttr(String JavaDoc fileName, String JavaDoc attrName, NbMarshalledObject obj) {
835             setAttr(fileName, attrName, obj);
836         }
837
838         /**
839          * Sets an attribute to the table.
840          * New added - for Sandwich project (XML format instead of serialization) .
841          * @param fileName - name of file
842          * @param attrName - name of attribute
843          * @param obj - attribute
844          */

845         final void setAttr(String JavaDoc fileName, String JavaDoc attrName, Object JavaDoc obj) {
846             XMLMapAttr m = (XMLMapAttr) get(fileName);
847
848             if (m == null) {
849                 m = new XMLMapAttr(); //HashMap (7);//XMLMapAttr();
850
put(fileName, m);
851             }
852
853             m.put(attrName, obj, false);
854
855             if ((obj == null) && (m.size() == 1)) {
856                 remove(fileName);
857             }
858
859             // increments the version
860
version++;
861         }
862
863         /** Enum of attributes for one file.
864         */

865         public Enumeration JavaDoc<String JavaDoc> attrs(String JavaDoc fileName) {
866             Map JavaDoc m = (Map JavaDoc) get(fileName);
867
868             if (m == null) {
869                 return Enumerations.empty();
870             } else {
871                 HashSet JavaDoc s = new HashSet JavaDoc(m.keySet());
872
873                 return Collections.enumeration(s);
874             }
875         }
876
877         /**
878          * Parses element: <CODE><Attributes version="1.0"></CODE>
879          * @return new instance of subclass (anonymous class)of ElementHandler
880          */

881         private ElementHandler parseFirstLevel() {
882             ElementHandler elemService = new ElementHandler() {
883                     private final String JavaDoc[] ELM_KEYS = { "ATTRIBUTES" }; // NOI18N
884
private final String JavaDoc[] MANDAT_ATTR_KEYS = { "VERSION" }; // NOI18N
885

886                     public void internalStartElement(String JavaDoc elemName, HashMap JavaDoc mapMandatory, HashMap JavaDoc mapAllowed)
887                     throws SAXException JavaDoc {
888                         // later can check version
889
}
890
891                     protected String JavaDoc[] getKeys() {
892                         return ELM_KEYS;
893                     }
894
895                     protected String JavaDoc[] getMandatoryAttrs() {
896                         return MANDAT_ATTR_KEYS;
897                     }
898                 };
899
900             return elemService;
901         }
902
903         /**
904          * Parses element: <CODE><fileobject name="fileName"></CODE>
905          * @param fileName is parsed from XML
906          * @return new instance of subclass (anonymous class)of ElementHandler
907          */

908         private ElementHandler parseSecondLevel(final StringBuffer JavaDoc fileName) {
909             ElementHandler elemService = new ElementHandler() {
910                     private final String JavaDoc[] ELM_KEYS = { "FILEOBJECT" }; // NOI18N
911
private final String JavaDoc[] MANDAT_ATTR_KEYS = { "NAME" }; // NOI18N
912

913                     public void internalStartElement(String JavaDoc elemName, HashMap JavaDoc mapMandatory, HashMap JavaDoc mapAllowed)
914                     throws SAXException JavaDoc {
915                         String JavaDoc temp;
916                         fileName.delete(0, fileName.length());
917                         temp = (String JavaDoc) mapMandatory.get("NAME"); // NOI18N
918

919                         if (temp == null) {
920                             temp = (String JavaDoc) mapMandatory.get("name"); // NOI18N
921
}
922
923                         if (temp != null) {
924                             fileName.append(temp);
925                         }
926                     }
927
928                     public void endElement(String JavaDoc elementName)
929                     throws SAXException JavaDoc {
930                     }
931
932                     protected String JavaDoc[] getKeys() {
933                         return ELM_KEYS;
934                     }
935
936                     protected String JavaDoc[] getMandatoryAttrs() {
937                         return MANDAT_ATTR_KEYS;
938                     }
939                 };
940
941             return elemService;
942         }
943
944         /**
945          * Parses element: <CODE><attr StringValue="This is attribute"></CODE>
946          * @param fileName is name of fileobject, which is assigned to attribute
947          * @return new instance of subclass (anonymous class)of ElementHandler
948          */

949         private ElementHandler parseThirdLevel(final StringBuffer JavaDoc fileName) {
950             ElementHandler elemService = new ElementHandler() {
951                     private final String JavaDoc[] ELM_KEYS = { "ATTR" }; // NOI18N
952
private final String JavaDoc[] MANDAT_ATTR_KEYS = { "NAME" }; // NOI18N
953

954                     public void internalStartElement(String JavaDoc elemName, HashMap JavaDoc mapMandatory, HashMap JavaDoc mapAllowed)
955                     throws SAXException JavaDoc {
956                         String JavaDoc attrName;
957
958                         if (mapAllowed.isEmpty()) {
959                             return;
960                         }
961
962                         attrName = (String JavaDoc) mapMandatory.get("NAME"); // NOI18N
963

964                         if (attrName == null) {
965                             attrName = (String JavaDoc) mapMandatory.get("name"); // NOI18N
966
}
967
968                         if (attrName == null) {
969                             return;
970                         }
971
972                         Iterator JavaDoc it = mapAllowed.entrySet().iterator();
973
974                         while (it.hasNext()) {
975                             Map.Entry JavaDoc pair = (Map.Entry JavaDoc) it.next();
976
977                             if (XMLMapAttr.Attr.isValid((String JavaDoc) pair.getKey()) != -1) {
978                                 XMLMapAttr.Attr attr = XMLMapAttr.createAttributeAndDecode(
979                                         (String JavaDoc) pair.getKey(), (String JavaDoc) pair.getValue()
980                                     );
981                                 setAttr(fileName.toString(), attrName, attr);
982                             }
983                         }
984                     }
985
986                     protected String JavaDoc[] getKeys() {
987                         return ELM_KEYS;
988                     }
989
990                     protected String JavaDoc[] getMandatoryAttrs() {
991                         return MANDAT_ATTR_KEYS;
992                     }
993
994                     protected String JavaDoc[] getAllowedAttrs() {
995                         return XMLMapAttr.Attr.getAttrTypes();
996                     }
997                      //ALLOWED_ATTR_KEYS
998
};
999
1000            return elemService;
1001        }
1002
1003        /** Writes itself to XML
1004         * @param pw is PrintWriter
1005         */

1006        public void writeToXML(PrintWriter JavaDoc pw) /*throws IOException */ {
1007            // list of names
1008
Iterator JavaDoc it = new TreeSet JavaDoc(keySet()).iterator();
1009            XMLMapAttr.writeHeading(pw);
1010
1011            while (it.hasNext()) {
1012                String JavaDoc file = (String JavaDoc) it.next();
1013                XMLMapAttr attr = (XMLMapAttr) get(file);
1014
1015                if ((attr != null) && !attr.isEmpty()) {
1016                    attr.write(pw, file, " "); // NOI18N
1017
}
1018            }
1019
1020            XMLMapAttr.writeEnding(pw);
1021        }
1022
1023        /**
1024         * Reads itself from XML format
1025         * New added - for Sandwich project (XML format instead of serialization) .
1026         * @param is input stream (which is parsed)
1027         * @return Table
1028         */

1029        public void readFromXML(InputStream JavaDoc is, boolean validate)
1030        throws SAXException JavaDoc {
1031            StringBuffer JavaDoc fileName = new StringBuffer JavaDoc();
1032            ElementHandler[] elmKeyService = { parseFirstLevel(), parseSecondLevel(fileName), parseThirdLevel(fileName) }; //
1033
String JavaDoc dtd = getClass().getClassLoader().getResource(DTD_PATH).toExternalForm();
1034            InnerParser parser = new InnerParser(PUBLIC_ID, dtd, elmKeyService);
1035
1036            try {
1037                parser.parseXML(is, validate);
1038            } catch (Exception JavaDoc ioe) {
1039                throw (SAXException JavaDoc) ExternalUtil.copyAnnotation(
1040                    new SAXException JavaDoc(NbBundle.getMessage(DefaultAttributes.class, "EXC_DefAttrReadErr")), ioe
1041                );
1042            } catch (FactoryConfigurationError JavaDoc fce) {
1043                // ??? see http://openide.netbeans.org/servlets/ReadMsg?msgId=340881&listName=dev
1044
throw (SAXException JavaDoc) ExternalUtil.copyAnnotation(
1045                    new SAXException JavaDoc(NbBundle.getMessage(DefaultAttributes.class, "EXC_DefAttrReadErr")), fce
1046                );
1047            }
1048        }
1049
1050        /** Writes external.
1051         * @param oo
1052         * @throws IOException */

1053        public void writeExternal(ObjectOutput JavaDoc oo) throws IOException JavaDoc {
1054            // list of names
1055
Iterator JavaDoc it = keySet().iterator();
1056
1057            while (it.hasNext()) {
1058                String JavaDoc file = (String JavaDoc) it.next();
1059                Map JavaDoc attr = (Map JavaDoc) get(file);
1060
1061                if ((attr != null) && !attr.isEmpty()) {
1062                    oo.writeObject(file);
1063
1064                    Iterator JavaDoc entries = attr.entrySet().iterator();
1065
1066                    while (entries.hasNext()) {
1067                        Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next();
1068                        String JavaDoc key = (String JavaDoc) entry.getKey();
1069                        Object JavaDoc value = entry.getValue();
1070
1071                        if ((key != null) && (value != null)) {
1072                            oo.writeObject(key);
1073                            oo.writeObject(value);
1074                        }
1075                    }
1076
1077                    oo.writeObject(null);
1078                }
1079            }
1080
1081            oo.writeObject(null);
1082        }
1083
1084        /** Reads external.
1085        */

1086        public void readExternal(ObjectInput JavaDoc oi) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1087            for (;;) {
1088                String JavaDoc file = (String JavaDoc) oi.readObject();
1089
1090                if (file == null) {
1091                    break;
1092                }
1093
1094                for (;;) {
1095                    String JavaDoc attr = (String JavaDoc) oi.readObject();
1096
1097                    if (attr == null) {
1098                        break;
1099                    }
1100
1101                    Object JavaDoc o = oi.readObject();
1102
1103                    // backward compatibility
1104
if (o instanceof java.rmi.MarshalledObject JavaDoc) {
1105                        o = ((java.rmi.MarshalledObject JavaDoc) o).get();
1106                        o = new NbMarshalledObject(o);
1107                    }
1108
1109                    // end of backward compatibility
1110
if (o instanceof NbMarshalledObject) {
1111                        setAttr(file, attr, o);
1112                    }
1113                }
1114            }
1115        }
1116    }
1117
1118    /** Element handler should be used as superclass for future classes. These future classes should be passed
1119     * to constructor of InnerParser as Array. (ElementHandler[]). Each subclass of ElementHandler is responsible for
1120     * processing one or more elements in XML file.
1121     * Each subclass of ElementHandler should overwrite one or more of these methods:
1122     * - protected String[] getKeys()
1123     * - protected String[] getMandatoryAttrs()
1124     * - protected String[] getAllowedAttrs()
1125     * - protected void endElement(String name) throws SAXException {}
1126     * - protected void characters(char[] ch, int start, int length) throws SAXException {}
1127     * - protected void internalStartElement(String elemName, HashMap mapMandatory,HashMap mapAllowed) throws SAXException {}
1128     */

1129    static abstract class ElementHandler {
1130        private static final String JavaDoc[] EMPTY = { };
1131        private int mandatAttrCount;
1132
1133        public void startElement(String JavaDoc elemName, Attributes JavaDoc attrs)
1134        throws SAXException JavaDoc {
1135            HashMap JavaDoc mapAllowed = new HashMap JavaDoc();
1136            HashMap JavaDoc mapMandatory = new HashMap JavaDoc();
1137
1138            if (checkAttributes(attrs, mapMandatory, mapAllowed) == false) {
1139                throw new SAXException JavaDoc(
1140                    NbBundle.getMessage(DefaultAttributes.class, "XML_InaccurateParam") + ": " + elemName
1141                ); // NOI18N
1142
}
1143
1144            internalStartElement(elemName, mapMandatory, mapAllowed);
1145        }
1146
1147        /** Inner parser calls this method to notify this class that start element was parsed (<someelement>)
1148         * @param elemName name of element
1149         * @param mapMandatory map(String attributeName,String attributeValue) which holds pairs attributeName and attributeValue, which are mandatory for this element
1150         * @param mapAllowed map(String attributeName,String attributeValue) which holds pairs attributeName and attributeValue, which are optional for this element
1151         * @throws SAXException
1152         */

1153        protected void internalStartElement(String JavaDoc elemName, HashMap JavaDoc mapMandatory, HashMap JavaDoc mapAllowed)
1154        throws SAXException JavaDoc {
1155        }
1156
1157        /** Inner parser calls this method to notify this class that there is content between start element and end element
1158         * @param ch[] array of characters found between start and end element
1159         * @param start is start position in ch[]
1160         * @param length is length of content
1161         * @throws SAXException
1162         */

1163        protected void characters(char[] ch, int start, int length)
1164        throws SAXException JavaDoc {
1165        }
1166
1167        /** Inner parser calls this method to notify this class that end element was parsed
1168         * @param elemName name of element
1169         * @throws SAXException
1170         */

1171        protected void endElement(String JavaDoc elemName) throws SAXException JavaDoc {
1172        }
1173
1174        /** @return names of elements which this class can process
1175         */

1176        protected String JavaDoc[] getKeys() {
1177            return EMPTY;
1178        }
1179
1180        /** @return names of attributes which are checked and are mandatory
1181         */

1182        protected String JavaDoc[] getMandatoryAttrs() {
1183            return getKeys();
1184        }
1185
1186        /** @return names of attributes which are allowed, are expected, but are not mandatory
1187         */

1188        protected String JavaDoc[] getAllowedAttrs() {
1189            return EMPTY;
1190        }
1191
1192        private int isMyTag(String JavaDoc name) {
1193            return isInArray(name, getKeys());
1194        }
1195
1196        private int isAllowedAttr(String JavaDoc name) {
1197            return isInArray(name, getAllowedAttrs());
1198        }
1199
1200        private boolean isMandatOK() {
1201            return (mandatAttrCount == getMandatoryAttrs().length);
1202        }
1203
1204        private int isMandatoryAttr(String JavaDoc name) {
1205            int retValue = isInArray(name, getMandatoryAttrs());
1206
1207            if (retValue != -1) {
1208                mandatAttrCount++;
1209            }
1210
1211            return retValue;
1212        }
1213
1214        private int isInArray(String JavaDoc name, String JavaDoc[] arr) {
1215            if ((arr == null) || (name == null)) {
1216                return -1;
1217            }
1218
1219            String JavaDoc correctStr = name.trim();
1220
1221            for (int i = 0; i < arr.length; i++) {
1222                if (correctStr.equalsIgnoreCase(arr[i]) == true) {
1223                    return i;
1224                }
1225            }
1226
1227            return -1;
1228        }
1229
1230        private boolean checkAttributes(Attributes JavaDoc attrList, HashMap JavaDoc mapMandatory, HashMap JavaDoc mapAllowed) {
1231            String JavaDoc temp;
1232            mandatAttrCount = 0;
1233
1234            if (attrList == null) {
1235                return false;
1236            }
1237
1238            for (int i = 0; i < attrList.getLength(); i++) {
1239                if (isMandatoryAttr(attrList.getQName(i)) != -1) {
1240                    temp = attrList.getQName(i).toUpperCase(Locale.ENGLISH);
1241                    mapMandatory.put(temp, attrList.getValue(i));
1242
1243                    continue;
1244                }
1245
1246                if (isAllowedAttr(attrList.getQName(i)) != -1) {
1247                    temp = attrList.getQName(i).toUpperCase(Locale.ENGLISH);
1248                    mapAllowed.put(temp, attrList.getValue(i));
1249
1250                    continue;
1251                }
1252            }
1253
1254            return isMandatOK();
1255        }
1256    }
1257
1258    /** Class that can be used to parse XML document (Expects array of ElementHandler clasess). Calls handler methods of ElementHandler clasess.
1259     */

1260    static class InnerParser extends DefaultHandler JavaDoc {
1261        private ElementHandler[] elmKeyService; // = {fileSystemElement(attrStack),folderElement(attrStack),fileElement(attrStack),attrElement(attrStack)};
1262
private String JavaDoc tagInProcess = ""; // NOI18N
1263
private String JavaDoc publicId;
1264        private String JavaDoc publicURL;
1265
1266        InnerParser(String JavaDoc publicId, String JavaDoc publicURL, ElementHandler[] elmKeyService) {
1267            this.elmKeyService = elmKeyService;
1268            this.publicId = publicId;
1269            this.publicURL = publicURL;
1270        }
1271
1272        /** Starts parsing document, that can be localized by means of uri parameter
1273         * @param validate
1274         * @param uri adress of document, that will be parsed
1275         * @throws ParserConfigurationException
1276         * @throws IOException
1277         * @throws SAXException */

1278        public void parseXML(String JavaDoc uri, boolean validate)
1279        throws IOException JavaDoc, SAXException JavaDoc, ParserConfigurationException JavaDoc, FactoryConfigurationError JavaDoc {
1280            XMLReader JavaDoc parser = getParser(validate);
1281            parser.parse(uri);
1282        }
1283
1284        /** Starts parsing document - if you have document`s InputStream
1285         * @param validate
1286         * @param is document`s InputStream
1287         * @throws ParserConfigurationException
1288         * @throws IOException
1289         * @throws SAXException */

1290        public void parseXML(InputStream JavaDoc is, boolean validate)
1291        throws IOException JavaDoc, SAXException JavaDoc, ParserConfigurationException JavaDoc, FactoryConfigurationError JavaDoc {
1292            InputSource JavaDoc iSource = new InputSource JavaDoc(is);
1293            XMLReader JavaDoc parser = getParser(validate);
1294            parser.parse(iSource);
1295        }
1296
1297        private XMLReader JavaDoc getParser(boolean validate)
1298        throws SAXException JavaDoc, ParserConfigurationException JavaDoc, FactoryConfigurationError JavaDoc {
1299            XMLReader JavaDoc parser = XMLUtil.createXMLReader(validate);
1300
1301            // create document handler and register it
1302
parser.setEntityResolver(this);
1303            parser.setContentHandler(this);
1304            parser.setErrorHandler(this);
1305
1306            return parser;
1307        }
1308
1309        public void error(SAXParseException JavaDoc exception)
1310        throws SAXException JavaDoc {
1311            throw exception;
1312        }
1313
1314        public void warning(SAXParseException JavaDoc exception)
1315        throws SAXException JavaDoc {
1316            throw exception;
1317        }
1318
1319        public void fatalError(SAXParseException JavaDoc exception)
1320        throws SAXException JavaDoc {
1321            throw exception;
1322        }
1323
1324        public void startElement(String JavaDoc uri, String JavaDoc lname, String JavaDoc name, Attributes JavaDoc attrs)
1325        throws SAXException JavaDoc {
1326            tagInProcess = name = name.trim();
1327
1328            for (int i = 0; i < elmKeyService.length; i++) {
1329                if (elmKeyService[i].isMyTag(name) != -1) {
1330                    elmKeyService[i].startElement(name, attrs);
1331
1332                    return;
1333                }
1334            }
1335
1336            throw new SAXException JavaDoc(NbBundle.getMessage(DefaultAttributes.class, "XML_UnknownElement") + " " + name); // NOI18N
1337
}
1338
1339        public void endElement(String JavaDoc uri, String JavaDoc lname, String JavaDoc name) throws SAXException JavaDoc {
1340            for (int i = 0; i < elmKeyService.length; i++) {
1341                if (elmKeyService[i].isMyTag(name.trim()) != -1) {
1342                    elmKeyService[i].endElement(name.trim());
1343
1344                    return;
1345                }
1346            }
1347
1348            throw new SAXException JavaDoc(NbBundle.getMessage(DefaultAttributes.class, "XML_UnknownElement") + " " + name); // NOI18N
1349
}
1350
1351        public void characters(char[] ch, int start, int length)
1352        throws SAXException JavaDoc {
1353            for (int i = 0; i < elmKeyService.length; i++) {
1354                if (elmKeyService[i].isMyTag(tagInProcess) != -1) {
1355                    elmKeyService[i].characters(ch, start, length);
1356
1357                    return;
1358                }
1359            }
1360
1361            throw new SAXException JavaDoc(
1362                NbBundle.getMessage(DefaultAttributes.class, "XML_UnknownElement") + " " + tagInProcess
1363            ); // NOI18N
1364
}
1365
1366        public InputSource JavaDoc resolveEntity(java.lang.String JavaDoc pid, java.lang.String JavaDoc sid)
1367        throws SAXException JavaDoc {
1368            if ((pid != null) && pid.equals(publicId)) {
1369                return new InputSource JavaDoc(publicURL);
1370            }
1371
1372            return new InputSource JavaDoc(sid);
1373        }
1374    }
1375}
1376
Popular Tags