001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.xml.xam.dom;
043:
044: import java.util.HashSet;
045:
046: /**
047: * @author Nam Nguyen
048: * @author ads
049: */
050: public final class Utils {
051:
052: public static boolean isValidNCName(String str) {
053: if (str == null || str.length() == 0) {
054: return false;
055: }
056: char ch = str.charAt(0);
057: if (!isNCNameStart(ch)) {
058: return false;
059: }
060: for (int i = 1; i < str.length(); i++) {
061: ch = str.charAt(i);
062: if (!isNCNameChar(ch)) {
063: return false;
064: }
065: }
066: return true;
067: }
068:
069: private static boolean isNCNameStart(int ch) {
070: return isBasechar(ch) || isIdeographic(ch) || ch == '_';
071: }
072:
073: private static boolean isNCNameChar(int ch) {
074: return isNCNameStart(ch) || Character.isDigit(ch) || ch == '.'
075: || ch == '-' || isCombiningChar(ch) || isExtender(ch);
076: }
077:
078: private static boolean isBasechar(int c) {
079: return BASECHARS.contains(c);
080: }
081:
082: private static boolean isIdeographic(int c) {
083: return IDEOGHAPHICS.contains(c);
084: }
085:
086: private static boolean isCombiningChar(int ch) {
087: return COMBININGS.contains(ch);
088: }
089:
090: private static boolean isExtender(int ch) {
091: return EXTENDERS.contains(ch);
092: }
093:
094: private static final HashSet<Integer> BASECHARS = new HashSet<Integer>();
095: private static final int[] BASECHARS_VALUES = new int[] { 0x0386,
096: 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0559, 0x06D5,
097: 0x093D, 0x09B2, 0x0A5E, 0x0A8D, 0x0ABD, 0x0AE0, 0x0B3D,
098: 0x0B9C, 0x0CDE, 0x0E30, 0x0E84, 0x0E8A, 0x0E8D, 0x0EA5,
099: 0x0EA7, 0x0EB0, 0x0EBD, 0x1100, 0x1109, 0x113C, 0x113E,
100: 0x1140, 0x114C, 0x114E, 0x1150, 0x1159, 0x1163, 0x1165,
101: 0x1167, 0x1169, 0x1175, 0x119E, 0x11A8, 0x11AB, 0x11BA,
102: 0x11EB, 0x11F0, 0x11F9, 0x1F59, 0x1F5B, 0x1F5D, 0x1FBE,
103: 0x2126, 0x212E };
104: private static final int[][] BASECHARS_RANGES = new int[][] {
105: { 0x0041, 0x005A }, { 0x0061, 0x007A }, { 0x00C0, 0x00D6 },
106: { 0x00D8, 0x00F6 }, { 0x00F8, 0x00FF }, { 0x0100, 0x0131 },
107: { 0x0134, 0x013E }, { 0x0141, 0x0148 }, { 0x014A, 0x017E },
108: { 0x0180, 0x01C3 }, { 0x01CD, 0x01F0 }, { 0x01F4, 0x01F5 },
109: { 0x01FA, 0x0217 }, { 0x0250, 0x02A8 }, { 0x02BB, 0x02C1 },
110: { 0x0388, 0x038A }, { 0x038E, 0x03A1 }, { 0x03A3, 0x03CE },
111: { 0x03D0, 0x03D6 }, { 0x03E2, 0x03F3 }, { 0x0401, 0x040C },
112: { 0x040E, 0x044F }, { 0x0451, 0x045C }, { 0x045E, 0x0481 },
113: { 0x0490, 0x04C4 }, { 0x04C7, 0x04C8 }, { 0x04CB, 0x04CC },
114: { 0x04D0, 0x04EB }, { 0x04EE, 0x04F5 }, { 0x04F8, 0x04F9 },
115: { 0x0531, 0x0556 }, { 0x0561, 0x0586 }, { 0x05D0, 0x05EA },
116: { 0x05F0, 0x05F2 }, { 0x0621, 0x063A }, { 0x0641, 0x064A },
117: { 0x0671, 0x06B7 }, { 0x06BA, 0x06BE }, { 0x06C0, 0x06CE },
118: { 0x06D0, 0x06D3 }, { 0x06E5, 0x06E6 }, { 0x0905, 0x0939 },
119: { 0x0958, 0x0961 }, { 0x0985, 0x098C }, { 0x098F, 0x0990 },
120: { 0x0993, 0x09A8 }, { 0x09AA, 0x09B0 }, { 0x09B6, 0x09B9 },
121: { 0x09DC, 0x09DD }, { 0x09DF, 0x09E1 }, { 0x09F0, 0x09F1 },
122: { 0x0A05, 0x0A0A }, { 0x0A0F, 0x0A10 }, { 0x0A13, 0x0A28 },
123: { 0x0A2A, 0x0A30 }, { 0x0A32, 0x0A33 }, { 0x0A35, 0x0A36 },
124: { 0x0A38, 0x0A39 }, { 0x0A59, 0x0A5C }, { 0x0A72, 0x0A74 },
125: { 0x0A85, 0x0A8B }, { 0x0A8F, 0x0A91 }, { 0x0A93, 0x0AA8 },
126: { 0x0AAA, 0x0AB0 }, { 0x0AB2, 0x0AB3 }, { 0x0AB5, 0x0AB9 },
127: { 0x0B05, 0x0B0C }, { 0x0B0F, 0x0B10 }, { 0x0B13, 0x0B28 },
128: { 0x0B2A, 0x0B30 }, { 0x0B32, 0x0B33 }, { 0x0B36, 0x0B39 },
129: { 0x0B5C, 0x0B5D }, { 0x0B5F, 0x0B61 }, { 0x0B85, 0x0B8A },
130: { 0x0B8E, 0x0B90 }, { 0x0B92, 0x0B95 }, { 0x0B99, 0x0B9A },
131: { 0x0B9E, 0x0B9F }, { 0x0BA3, 0x0BA4 }, { 0x0BA8, 0x0BAA },
132: { 0x0BAE, 0x0BB5 }, { 0x0BB7, 0x0BB9 }, { 0x0C05, 0x0C0C },
133: { 0x0C0E, 0x0C10 }, { 0x0C12, 0x0C28 }, { 0x0C2A, 0x0C33 },
134: { 0x0C35, 0x0C39 }, { 0x0C60, 0x0C61 }, { 0x0C85, 0x0C8C },
135: { 0x0C8E, 0x0C90 }, { 0x0C92, 0x0CA8 }, { 0x0CAA, 0x0CB3 },
136: { 0x0CB5, 0x0CB9 }, { 0x0CE0, 0x0CE1 }, { 0x0D05, 0x0D0C },
137: { 0x0D0E, 0x0D10 }, { 0x0D12, 0x0D28 }, { 0x0D2A, 0x0D39 },
138: { 0x0D60, 0x0D61 }, { 0x0E01, 0x0E2E }, { 0x0E32, 0x0E33 },
139: { 0x0E40, 0x0E45 }, { 0x0E81, 0x0E82 }, { 0x0E87, 0x0E88 },
140: { 0x0E94, 0x0E97 }, { 0x0E99, 0x0E9F }, { 0x0EA1, 0x0EA3 },
141: { 0x0EAA, 0x0EAB }, { 0x0EAD, 0x0EAE }, { 0x0EB2, 0x0EB3 },
142: { 0x0EC0, 0x0EC4 }, { 0x0F40, 0x0F47 }, { 0x0F49, 0x0F69 },
143: { 0x10A0, 0x10C5 }, { 0x10D0, 0x10F6 }, { 0x1102, 0x1103 },
144: { 0x1105, 0x1107 }, { 0x110B, 0x110C }, { 0x110E, 0x1112 },
145: { 0x1154, 0x1155 }, { 0x115F, 0x1161 }, { 0x116D, 0x116E },
146: { 0x1172, 0x1173 }, { 0x11AE, 0x11AF }, { 0x11B7, 0x11B8 },
147: { 0x11BC, 0x11C2 }, { 0x1E00, 0x1E9B }, { 0x1EA0, 0x1EF9 },
148: { 0x1F00, 0x1F15 }, { 0x1F18, 0x1F1D }, { 0x1F20, 0x1F45 },
149: { 0x1F48, 0x1F4D }, { 0x1F50, 0x1F57 }, { 0x1F5F, 0x1F7D },
150: { 0x1F80, 0x1FB4 }, { 0x1FB6, 0x1FBC }, { 0x1FC2, 0x1FC4 },
151: { 0x1FC6, 0x1FCC }, { 0x1FD0, 0x1FD3 }, { 0x1FD6, 0x1FDB },
152: { 0x1FE0, 0x1FEC }, { 0x1FF2, 0x1FF4 }, { 0x1FF6, 0x1FFC },
153: { 0x212A, 0x212B }, { 0x2180, 0x2182 }, { 0x3041, 0x3094 },
154: { 0x30A1, 0x30FA }, { 0x3105, 0x312C }, { 0xAC00, 0xD7A3 } };
155: static {
156: for (int c : BASECHARS_VALUES) {
157: BASECHARS.add(c);
158: }
159: for (int[] range : BASECHARS_RANGES) {
160: for (int c = range[0]; c <= range[1]; c++) {
161: BASECHARS.add(c);
162: }
163: }
164: }
165:
166: private static final HashSet<Integer> COMBININGS = new HashSet<Integer>();
167: private static final int[] COMBININGS_VALUES = new int[] { 0x05BF,
168: 0x05C4, 0x0670, 0x093C, 0x094D, 0x09BC, 0x09BE, 0x09BF,
169: 0x09D7, 0x0A02, 0x0A3C, 0x0A3E, 0x0A3F, 0x0ABC, 0x0B3C,
170: 0x0BD7, 0x0D57, 0x0E31, 0x0EB1, 0x0F35, 0x0F37, 0x0F39,
171: 0x0F3E, 0x0F3F, 0x0F97, 0x0FB9, 0x20E1, 0x3099, 0x309A };
172: private static final int[][] COMBININGS_RANGES = new int[][] {
173: { 0x0300, 0x0345 }, { 0x0360, 0x0361 }, { 0x0483, 0x0486 },
174: { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 }, { 0x05BB, 0x05BD },
175: { 0x05C1, 0x05C2 }, { 0x064B, 0x0652 }, { 0x06D6, 0x06DC },
176: { 0x06DD, 0x06DF }, { 0x06E0, 0x06E4 }, { 0x06E7, 0x06E8 },
177: { 0x06EA, 0x06ED }, { 0x0901, 0x0903 }, { 0x093E, 0x094C },
178: { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0983 },
179: { 0x09C0, 0x09C4 }, { 0x09C7, 0x09C8 }, { 0x09CB, 0x09CD },
180: { 0x09E2, 0x09E3 }, { 0x0A40, 0x0A42 }, { 0x0A47, 0x0A48 },
181: { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A83 },
182: { 0x0ABE, 0x0AC5 }, { 0x0AC7, 0x0AC9 }, { 0x0ACB, 0x0ACD },
183: { 0x0B01, 0x0B03 }, { 0x0B3E, 0x0B43 }, { 0x0B47, 0x0B48 },
184: { 0x0B4B, 0x0B4D }, { 0x0B56, 0x0B57 }, { 0x0B82, 0x0B83 },
185: { 0x0BBE, 0x0BC2 }, { 0x0BC6, 0x0BC8 }, { 0x0BCA, 0x0BCD },
186: { 0x0C01, 0x0C03 }, { 0x0C3E, 0x0C44 }, { 0x0C46, 0x0C48 },
187: { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0C82, 0x0C83 },
188: { 0x0CBE, 0x0CC4 }, { 0x0CC6, 0x0CC8 }, { 0x0CCA, 0x0CCD },
189: { 0x0CD5, 0x0CD6 }, { 0x0D02, 0x0D03 }, { 0x0D3E, 0x0D43 },
190: { 0x0D46, 0x0D48 }, { 0x0D4A, 0x0D4D }, { 0x0E34, 0x0E3A },
191: { 0x0E47, 0x0E4E }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
192: { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F71, 0x0F84 },
193: { 0x0F86, 0x0F8B }, { 0x0F90, 0x0F95 }, { 0x0F99, 0x0FAD },
194: { 0x0FB1, 0x0FB7 }, { 0x20D0, 0x20DC }, { 0x302A, 0x302F } };
195: static {
196: for (int c : COMBININGS_VALUES) {
197: COMBININGS.add(c);
198: }
199: for (int[] range : COMBININGS_RANGES) {
200: for (int c = range[0]; c <= range[1]; c++) {
201: COMBININGS.add(c);
202: }
203: }
204: }
205:
206: static HashSet<Integer> EXTENDERS = new HashSet<Integer>();
207: static {
208: EXTENDERS.add(0x00B7);
209: EXTENDERS.add(0x02D0);
210: EXTENDERS.add(0x02D1);
211: EXTENDERS.add(0x0387);
212: EXTENDERS.add(0x0640);
213: EXTENDERS.add(0x0E46);
214: EXTENDERS.add(0x0EC6);
215: EXTENDERS.add(0x3005);
216: addRange(EXTENDERS, 0x3031, 0x3035);
217: addRange(EXTENDERS, 0x309D, 0x309E);
218: addRange(EXTENDERS, 0x30FC, 0x30FE);
219: }
220:
221: static HashSet<Integer> IDEOGHAPHICS = new HashSet<Integer>();
222: static {
223: addRange(IDEOGHAPHICS, 0x4E00, 0x9FA5);
224: IDEOGHAPHICS.add(0x3007);
225: addRange(IDEOGHAPHICS, 0x3021, 0x3029);
226: };
227:
228: static void addRange(HashSet<Integer> set, int start, int end) {
229: for (int c = start; c <= end; c++) {
230: set.add(c);
231: }
232: }
233: }
|