KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > om > NamePool


1 package com.icl.saxon.om;
2 import com.icl.saxon.style.StandardNames;
3 import javax.xml.transform.TransformerException JavaDoc;
4 import java.util.StringTokenizer JavaDoc;
5 import java.util.Vector JavaDoc;
6
7 /**
8   * An object representing a collection of XML names, each containing a Namespace URI,
9   * a Namespace prefix, and a local name; plus a collection of namespaces, each
10   * consisting of a prefix/URI pair. <br>
11   *
12   * <p>The equivalence betweem names depends only on the URI and the local name.
13   * The prefix is retained for documentary purposes only: it is useful when
14   * reconstructing a document to use prefixes that the user is familiar with.</p>
15   *
16   * <p>The NamePool eliminates duplicate names if they have the same prefix, uri,
17   * and local part. It retains duplicates if they have different prefixes</p>
18   *
19   *
20   * @author <A HREF="mailto:mhkay@iclway.co.uk>Michael H. Kay</A>
21   */

22
23 public class NamePool {
24     
25     // The NamePool holds two kinds of entry: name entries, representing
26
// expanded names (local name + prefix + URI), identified by a name code,
27
// and namespace entries (prefix + URI) identified by a namespace code.
28
//
29
// The data structure of the name table is as follows.
30
//
31
// There is a fixed size hash table; names are allocated to slots in this
32
// table by hashing on the local name. Each entry in the table is the head of
33
// a chain of NameEntry objects representing names that have the same hash code.
34
//
35
// Each NameEntry represents a distinct name (same URI and local name). It contains
36
// The local name as a string, plus a short integer representing the URI (as an
37
// offset into the array uris[]).
38
//
39
// The fingerprint of a name consists of the hash slot number concatenated with
40
// the depth of the entry down the chain of hash synonyms.
41
//
42
// A nameCode contains the fingerprint in the bottom 20 bits. It also contains
43
// an 8-bit prefix index. This distinguishes the prefix used, among all the
44
// prefixes that have been used with this namespace URI. If the prefix index is
45
// zero, the prefix is null. Otherwise, it indexes an space-separated list of
46
// prefix Strings associated with the namespace URI.
47

48
49     // The default singular instance, used unless the user deliberately wants to
50
// manage name pools himself
51

52     private static NamePool defaultNamePool = new NamePool();
53     static {
54         defaultNamePool.loadStandardNames();
55     }
56     
57     private StandardNames standardNames = null;
58     
59     /**
60     * Get the singular default NamePool
61     */

62     
63     public static NamePool getDefaultNamePool() {
64         return defaultNamePool;
65     }
66         
67     
68     private class NameEntry {
69         String JavaDoc localName;
70         short uriCode;
71         NameEntry nextEntry; // next NameEntry with the same hashcode
72

73         public NameEntry(short uriCode, String JavaDoc localName) {
74             this.uriCode = uriCode;
75             this.localName = localName;
76             this.nextEntry = null;
77         }
78             
79     }
80     
81     NameEntry[] hashslots = new NameEntry[1024];
82     
83     String JavaDoc[] prefixes = new String JavaDoc[100];
84     short prefixesUsed = 0;
85     String JavaDoc[] uris = new String JavaDoc[100];
86     String JavaDoc[] prefixesForUri = new String JavaDoc[100];
87     short urisUsed = 0;
88     Vector JavaDoc signatures = new Vector JavaDoc(); // records the stylesheets present in this namepool
89
boolean sealed = false; // indicates that no new entries are allowed
90

91 // NOTE: signatures are no longer used in 6.5.2. However, the mechanism is retained "just in case".
92
// It's been deleted in the 7.1 code base.
93

94     public NamePool() {
95
96         prefixes[Namespace.NULL_CODE] = "";
97         uris[Namespace.NULL_CODE] = Namespace.NULL;
98         prefixesForUri[Namespace.NULL_CODE] = "";
99
100         prefixes[Namespace.XML_CODE] = "xml";
101         uris[Namespace.XML_CODE] = Namespace.XML;
102         prefixesForUri[Namespace.XML_CODE] = "xml ";
103
104         prefixes[Namespace.XSLT_CODE] = "xsl";
105         uris[Namespace.XSLT_CODE] = Namespace.XSLT;
106         prefixesForUri[Namespace.XSLT_CODE] = "xsl ";
107
108         prefixes[Namespace.SAXON_CODE] = "saxon";
109         uris[Namespace.SAXON_CODE] = Namespace.SAXON;
110         prefixesForUri[Namespace.SAXON_CODE] = "saxon ";
111
112         prefixes[Namespace.EXSLT_FUNCTIONS_CODE] = "func";
113         uris[Namespace.EXSLT_FUNCTIONS_CODE] = Namespace.EXSLT_FUNCTIONS;
114         prefixesForUri[Namespace.EXSLT_FUNCTIONS_CODE] = "func ";
115
116         prefixesUsed = 5;
117         urisUsed = 5;
118
119     }
120     
121     /**
122     * Load the standard names that have a special meaning to XSLT
123     */

124     
125     public synchronized void loadStandardNames() {
126         if (standardNames==null) {
127             standardNames = new StandardNames(this);
128             standardNames.allocateNames();
129         }
130     }
131
132     /**
133     * Get the standard names
134     */

135     
136     public StandardNames getStandardNames() {
137         return standardNames;
138     }
139     
140     /**
141     * Mark the NamePool to indicate that it contains names defined in a
142     * particular stylesheet
143     */

144
145     public synchronized void setStylesheetSignature(Object JavaDoc sig) {
146              // System.err.println("Setting signature " + sig + " in namepool " + this);
147
signatures.addElement(new Integer JavaDoc(sig.hashCode()));
148             // avoid keeping an object reference that locks the stylesheet into memory
149
}
150
151     /**
152     * Test whether the namepool contains names defined in a particular
153     * Stylesheet
154     */

155     
156     public boolean hasSignature(Object JavaDoc sig) {
157             // System.err.println("Testing for signature " + sig + " in namepool " + this);
158
// System.err.println("Found signature? " + signatures.contains(sig));
159

160         return signatures.contains(new Integer JavaDoc(sig.hashCode()));
161     }
162
163     /**
164     * Import the names defined in another namepool (typically the one used
165     * to create the stylesheet: these names are imported into the namepool
166     * used to build the source document).
167     * No longer used unless name pools are managed manually
168     */

169
170     public synchronized void importPool(NamePool other) throws TransformerException JavaDoc {
171
172             // System.err.println("Importing namepool " + other + " into namepool " + this);
173

174         if (signatures.size()>0) {
175             throw new TransformerException JavaDoc("Cannot merge names into a non-empty namepool");
176         }
177         
178         for (int s=0; s<other.signatures.size(); s++) {
179             signatures.addElement(other.signatures.elementAt(s));
180         }
181
182         for (int i=0; i<1024; i++) {
183             NameEntry entry = other.hashslots[i];
184             NameEntry prev = null;
185             while (entry != null) {
186                 NameEntry copy = new NameEntry(entry.uriCode, entry.localName);
187                 if (prev==null) {
188                     hashslots[i] = copy;
189                 } else {
190                     prev.nextEntry = copy;
191                 }
192                 prev = copy;
193                 entry = entry.nextEntry;
194             }
195         }
196
197         this.prefixesUsed = other.prefixesUsed;
198         this.urisUsed = other.urisUsed;
199         if (prefixesUsed > 60) {
200             this.prefixes = new String JavaDoc[prefixesUsed * 2];
201         }
202         if (urisUsed > 60) {
203             this.uris = new String JavaDoc[urisUsed * 2];
204             this.prefixesForUri = new String JavaDoc[urisUsed * 2];
205         }
206         System.arraycopy(other.prefixes, 0, this.prefixes, 0, prefixesUsed);
207         System.arraycopy(other.uris, 0, this.uris, 0, urisUsed);
208         System.arraycopy(other.prefixesForUri, 0, this.prefixesForUri, 0, urisUsed);
209         
210         other.sealed = true;
211     }
212
213     /**
214     * Determine whether the namepool is sealed
215     */

216     
217     public boolean isSealed() {
218         return sealed;
219     }
220     
221     /**
222     * Get a name entry corresponding to a given name code
223     * @return null if there is none.
224     */

225     
226     private NameEntry getNameEntry(int nameCode) {
227         int hash = nameCode & 0x3ff;
228         int depth = (nameCode >> 10) & 0x3ff;
229         NameEntry entry = hashslots[hash];
230         
231         for (int i=0; i<depth; i++) {
232             if (entry==null) return null;
233             entry = entry.nextEntry;
234         }
235         return entry;
236     }
237
238     /**
239     * Allocate the namespace code for a namespace prefix/URI pair.
240     * Create it if not already present
241     */

242     
243     public synchronized int allocateNamespaceCode(String JavaDoc prefix, String JavaDoc uri) {
244                 // System.err.println("allocate nscode for " + prefix + " = " + uri);
245

246         int prefixCode = allocateCodeForPrefix(prefix);
247         int uriCode = allocateCodeForURI(uri);
248         
249         if (prefixCode!=0) {
250             // ensure the prefix is in the list of prefixes used with this URI
251
String JavaDoc key = prefix + " ";
252             if (prefixesForUri[uriCode].indexOf(key) < 0) {
253                 prefixesForUri[uriCode] += key;
254             }
255         }
256                  
257         return (prefixCode<<16) + uriCode;
258     }
259
260     /**
261     * Get the existing namespace code for a namespace prefix/URI pair.
262     * @return -1 if there is none present
263     */

264     
265     public int getNamespaceCode(String JavaDoc prefix, String JavaDoc uri) {
266                 //System.err.println("get nscode for " + prefix + " = " + uri);
267
int prefixCode = getCodeForPrefix(prefix);
268         if (prefixCode<0) return -1;
269         int uriCode = getCodeForURI(uri);
270         if (uriCode<0) return -1;
271         
272         if (prefixCode!=0) {
273             // ensure the prefix is in the list of prefixes used with this URI
274
String JavaDoc key = prefix + " ";
275             if (prefixesForUri[uriCode].indexOf(key) < 0) {
276                 return -1;
277             }
278         }
279                  
280         return (prefixCode<<16) + uriCode;
281     }
282
283     /**
284     * Allocate the uri code for a given URI;
285     * create one if not found, unless the namepool is sealed
286     */

287     
288     public synchronized short allocateCodeForURI(String JavaDoc uri) {
289                     //System.err.println("allocate code for URI " + uri);
290
for (short j=0; j<urisUsed; j++) {
291             if (uris[j].equals(uri)) {
292                 return j;
293             }
294         }
295         if (sealed) {
296             throw new IllegalArgumentException JavaDoc("Namepool has been sealed");
297         }
298         if (urisUsed >= uris.length) {
299             if (urisUsed>32000) {
300                 throw new IllegalArgumentException JavaDoc("Too many namespace URIs");
301             }
302             String JavaDoc[] p = new String JavaDoc[urisUsed*2];
303             String JavaDoc[] u = new String JavaDoc[urisUsed*2];
304             System.arraycopy(prefixesForUri, 0, p, 0, urisUsed);
305             System.arraycopy(uris, 0, u, 0, urisUsed);
306             prefixesForUri = p;
307             uris = u;
308         }
309         uris[urisUsed] = uri;
310         prefixesForUri[urisUsed] = "";
311         return urisUsed++;
312     }
313     
314
315
316     /**
317     * Get the uri code for a given URI
318     * @return -1 if not present in the name pool
319     */

320     
321     public short getCodeForURI(String JavaDoc uri) {
322         for (short j=0; j<urisUsed; j++) {
323             if (uris[j].equals(uri)) {
324                 return j;
325             }
326         }
327         return -1;
328     }
329
330     /**
331     * Allocate the prefix code for a given Prefix; create one if not found
332     */

333     
334     public synchronized short allocateCodeForPrefix(String JavaDoc prefix) {
335         for (short i=0; i<prefixesUsed; i++) {
336             if (prefixes[i].equals(prefix)) {
337                 return i;
338             }
339         }
340         if (sealed) {
341             throw new IllegalArgumentException JavaDoc("Namepool has been sealed");
342         }
343         if (prefixesUsed >= prefixes.length) {
344             if (prefixesUsed>32000) {
345                 throw new IllegalArgumentException JavaDoc("Too many namespace prefixes");
346             }
347             String JavaDoc[] p = new String JavaDoc[prefixesUsed*2];
348             System.arraycopy(prefixes, 0, p, 0, prefixesUsed);
349             prefixes = p;
350         }
351         prefixes[prefixesUsed] = prefix;
352         return prefixesUsed++;
353     }
354
355     
356     /**
357     * Get the prefix code for a given Prefix
358     * @return -1 if not found
359     */

360     
361     public short getCodeForPrefix(String JavaDoc prefix) {
362         for (short i=0; i<prefixesUsed; i++) {
363             if (prefixes[i].equals(prefix)) {
364                 return i;
365             }
366         }
367         return -1;
368     }
369     
370     /**
371     * Get the index of a prefix among all the prefixes used with a given URI
372     * @return -1 if not found
373     */

374     
375     public int getPrefixIndex(short uriCode, String JavaDoc prefix) {
376         
377         // look for quick wins
378
if (prefix.equals("")) return 0;
379         if (prefixesForUri[uriCode].equals(prefix+" ")) return 1;
380         
381         // search for the prefix in the list
382
int i = 1;
383         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(prefixesForUri[uriCode]);
384         while (tok.hasMoreElements()) {
385             if (prefix.equals(tok.nextElement())) {
386                 return i;
387             }
388             if (i++==255) {
389                 throw new IllegalArgumentException JavaDoc("Too many prefixes for one namespace URI");
390             }
391         }
392         return -1;
393     }
394
395     /**
396     * Get a prefix among all the prefixes used with a given URI, given its index
397     * @return null if not found
398     */

399     
400     public String JavaDoc getPrefixWithIndex(short uriCode, int index) {
401         if (index==0) return "";
402         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(prefixesForUri[uriCode]);
403         int i=1;
404         while (tok.hasMoreElements()) {
405             String JavaDoc prefix = (String JavaDoc)tok.nextElement();
406             if (i++ == index) {
407                 return prefix;
408             }
409         }
410         return null;
411     }
412
413     /**
414     * Allocate a name from the pool, or a new Name if there is not a matching one there
415     * @param prefix
416     * @param uri - the namespace URI
417     * @param localName
418     * @return an integer (the "namecode") identifying the name within the namepool.
419     * The Name itself may be retrieved using the getName(int) method
420     */

421     
422     public synchronized int allocate(String JavaDoc prefix, String JavaDoc uri, String JavaDoc localName) {
423         short uriCode = allocateCodeForURI(uri);
424         return allocate(prefix, uriCode, localName);
425     }
426
427     /**
428     * Allocate a name from the pool, or a new Name if there is not a matching one there
429     * @param prefix
430     * @param uriCode - the code of the URI
431     * @param localName
432     * @return an integer (the "namecode") identifying the name within the namepool.
433     */

434     
435     public synchronized int allocate(String JavaDoc prefix, short uriCode, String JavaDoc localName) {
436                 // System.err.println("Allocate " + prefix + " : " + uriCode + " : " + localName);
437
int hash = (localName.hashCode() & 0x7fffffff) % 1023;
438         int depth = 0;
439         int prefixIndex = getPrefixIndex(uriCode, prefix);
440
441         if (prefixIndex<0) {
442             prefixesForUri[uriCode] += (prefix + " ");
443             prefixIndex = getPrefixIndex(uriCode, prefix);
444         }
445         NameEntry entry = null;
446         
447         if (hashslots[hash]==null) {
448             if (sealed) {
449                 throw new IllegalArgumentException JavaDoc("Namepool has been sealed");
450             }
451             entry = new NameEntry(uriCode, localName);
452             hashslots[hash] = entry;
453         } else {
454             entry = hashslots[hash];
455             while (true) {
456                 boolean sameLocalName = (entry.localName.equals(localName));
457                 boolean sameURI = (entry.uriCode==uriCode);
458
459                 if (sameLocalName && sameURI) {
460                             // may need to add a new prefix to the entry
461
break;
462                 } else {
463                     NameEntry next = entry.nextEntry;
464                     depth++;
465                     if (depth >= 1024) {
466                         throw new java.lang.IllegalArgumentException JavaDoc("Saxon name pool is full");
467                     }
468                     if (next==null) {
469                         if (sealed) {
470                             throw new IllegalArgumentException JavaDoc("Namepool has been sealed");
471                         }
472                         NameEntry newentry = new NameEntry(uriCode, localName);
473                         entry.nextEntry = newentry;
474                         break;
475                     } else {
476                         entry = next;
477                     }
478                 }
479             }
480         }
481         // System.err.println("name code = " + prefixIndex + "/" + depth + "/" + hash);
482
return ((prefixIndex<<20) + (depth<<10) + hash);
483     }
484
485     /**
486     * Allocate a namespace code for the prefix/URI of a given namecode
487     */

488     
489     public synchronized int allocateNamespaceCode(int namecode) {
490         String JavaDoc prefix = getPrefix(namecode);
491         int uriCode = getURICode(namecode);
492         int prefixCode = allocateCodeForPrefix(prefix);
493         return (prefixCode<<16) + uriCode;
494     }
495
496     
497     /**
498     * Get a namespace code for the prefix/URI of a given namecode
499     */

500     
501     public int getNamespaceCode(int namecode) {
502         String JavaDoc prefix = getPrefix(namecode);
503         int uriCode = getURICode(namecode);
504         int prefixCode = getCodeForPrefix(prefix);
505         return (prefixCode<<16) + uriCode;
506     }
507
508     /**
509     * Get the namespace-URI of a name, given its name code or fingerprint
510     */

511     
512     public String JavaDoc getURI(int nameCode) {
513         NameEntry entry = getNameEntry(nameCode);
514         if (entry==null) {
515             unknownNameCode(nameCode);
516         }
517         return uris[entry.uriCode];
518     }
519
520     /**
521     * Get the URI code of a name, given its name code or fingerprint
522     */

523     
524     public short getURICode(int nameCode) {
525         NameEntry entry = getNameEntry(nameCode);
526         if (entry==null) {
527             unknownNameCode(nameCode);
528         }
529         return entry.uriCode;
530     }
531
532     /**
533     * Get the local part of a name, given its name code or fingerprint
534     */

535     
536     public String JavaDoc getLocalName(int nameCode) {
537         NameEntry entry = getNameEntry(nameCode);
538         if (entry==null) {
539             unknownNameCode(nameCode);
540         }
541         return entry.localName;
542     }
543
544     /**
545     * Get the prefix part of a name, given its name code or fingerprint
546     */

547     
548     public String JavaDoc getPrefix(int nameCode) {
549         short uriCode = getURICode(nameCode);
550         int prefixIndex = (nameCode >> 20) & 0xff;
551         return getPrefixWithIndex(uriCode, prefixIndex);
552     }
553     
554     /**
555     * Get the display form of a name (the QName), given its name code or fingerprint
556     */

557     
558     public String JavaDoc getDisplayName(int nameCode) {
559         NameEntry entry = getNameEntry(nameCode);
560         if (entry==null) {
561             unknownNameCode(nameCode);
562         }
563         int prefixIndex = (nameCode >> 20) & 0xff;
564         if (prefixIndex==0) return entry.localName;
565         return getPrefixWithIndex(entry.uriCode, prefixIndex) + ':' + entry.localName;
566     }
567
568     /**
569     * Internal error: name not found in namepool
570     * (Usual cause is allocating a name code from one name pool and trying to
571     * find it in another)
572     */

573
574     private void unknownNameCode(int nameCode) {
575         System.err.println("Unknown name code " + nameCode);
576         diagnosticDump();
577         (new IllegalArgumentException JavaDoc("Unknown name")).printStackTrace();
578         throw new IllegalArgumentException JavaDoc("Unknown name code " + nameCode);
579     }
580     
581     /**
582     * Get a fingerprint for the name with a given name code.
583     * The signature has the property that if two signatures are the same, the names
584     * are the same (ie. same local name and same URI)
585     */

586     
587     public int getFingerprint(int nameCode) {
588         return nameCode & 0xfffff; // 20 bits: mask out the prefix and node type parts
589
}
590
591     /**
592     * Get a fingerprint for the name with a given uri and local name.
593     * These must be present in the NamePool.
594     * The signature has the property that if two signatures are the same, the names
595     * are the same (ie. same local name and same URI).
596     * @return -1 if not found
597     */

598     
599     public int getFingerprint(String JavaDoc uri, String JavaDoc localName) {
600         // A read-only version of allocate()
601

602         short uriCode = -1;
603         for (short j=0; j<urisUsed; j++) {
604             if (uris[j].equals(uri)) {
605                 uriCode = j;
606                 break;
607             }
608         }
609         
610         if (uriCode==-1) return -1;
611         
612         int hash = (localName.hashCode() & 0x7fffffff) % 1023;
613         int depth = 0;
614
615         NameEntry entry = null;
616         
617         if (hashslots[hash]==null) {
618             return -1;
619         } else {
620             entry = hashslots[hash];
621             while (true) {
622                 boolean sameLocalName = (entry.localName.equals(localName));
623                 boolean sameURI = (entry.uriCode==uriCode);
624
625                 if (sameLocalName && sameURI) {
626                     break;
627                 } else {
628                     NameEntry next = entry.nextEntry;
629                     depth++;
630                     if (next==null) {
631                         return -1;
632                     } else {
633                         entry = next;
634                     }
635                 }
636             }
637         }
638         return (depth<<10) + hash;
639     }
640
641     /**
642     * Get the namespace URI from a namespace code
643     */

644     
645     public String JavaDoc getURIFromNamespaceCode(int code) {
646         return uris[code&0xffff];
647     }
648
649     /**
650     * Get the namespace URI from a URI code
651     */

652     
653     public String JavaDoc getURIFromURICode(short code) {
654         return uris[code];
655     }
656
657     /**
658     * Get the namespace prefix from a namespace code
659     */

660     
661     public String JavaDoc getPrefixFromNamespaceCode(int code) {
662             // System.err.println("get prefix for " + code);
663
return prefixes[code>>16];
664     }
665
666
667     
668     /**
669     * Diagnostic print of the namepool contents
670     */

671     
672     public synchronized void diagnosticDump() {
673         System.err.println("Contents of NamePool " + this);
674         for (int i=0; i<1024; i++) {
675             NameEntry entry = hashslots[i];
676             int depth = 0;
677             while (entry != null) {
678                 System.err.println("Fingerprint " + depth + "/" + i);
679                 System.err.println(" local name = " + entry.localName +
680                                      " uri code = " + entry.uriCode);
681                 entry = entry.nextEntry;
682                 depth++;
683             }
684         }
685
686         for (int p=0; p<prefixesUsed; p++) {
687             System.err.println("Prefix " + p + " = " + prefixes[p]);
688         }
689         for (int u=0; u<urisUsed; u++) {
690             System.err.println("URI " + u + " = " + uris[u]);
691             System.err.println("Prefixes for URI " + u + " = " + prefixesForUri[u]);
692         }
693     }
694
695     /**
696     * The following code is used to create a list of Java declarations for
697     * the fingerprints of standard names used in a stylesheet. This code is
698     * executed while building Saxon, to create the constant definitions appearing
699     * in the StandardNames module.
700     */

701     
702     public void generateJavaConstants() {
703         System.out.println("// Declarations generated from NamePool");
704         for (int i=0; i<1024; i++) {
705             NameEntry entry = hashslots[i];
706             int depth = 0;
707             while (entry != null) {
708                 int fingerprint = (depth<<10) + i;
709                 String JavaDoc prefix="";
710                 if (entry.uriCode==Namespace.NULL_CODE) prefix="";
711                 else if (entry.uriCode==Namespace.XSLT_CODE) prefix="XSL_";
712                 else if (entry.uriCode==Namespace.XML_CODE) prefix="XML_";
713                 else if (entry.uriCode==Namespace.SAXON_CODE) prefix="SAXON_";
714                 String JavaDoc localname = entry.localName.toUpperCase();
715                 while (true) {
716                     int h = localname.indexOf('-');
717                     if (h<0) break;
718                     localname = localname.substring(0, h) + '_' + localname.substring(h+1);
719                 }
720                 
721                 System.out.println("public final static int " +
722                              prefix + localname + " = " + fingerprint + ";");
723                 entry = entry.nextEntry;
724                 depth++;
725             }
726         }
727     }
728         
729
730
731 }
732
733 //
734
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
735
// you may not use this file except in compliance with the License. You may obtain a copy of the
736
// License at http://www.mozilla.org/MPL/
737
//
738
// Software distributed under the License is distributed on an "AS IS" basis,
739
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
740
// See the License for the specific language governing rights and limitations under the License.
741
//
742
// The Original Code is: all this file.
743
//
744
// The Initial Developer of the Original Code is
745
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
746
//
747
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
748
//
749
// Contributor(s): none.
750
//
751
Popular Tags