1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import org.apache.hadoop.classification.InterfaceAudience;
22 import org.apache.hadoop.classification.InterfaceStability;
23 import org.apache.hadoop.hbase.util.Bytes;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 @InterfaceAudience.Public
44 @InterfaceStability.Evolving
45 public final class TableName implements Comparable<TableName> {
46
47
48
49 public final static char NAMESPACE_DELIM = ':';
50
51
52
53
54
55 public static final String VALID_NAMESPACE_REGEX =
56 "(?:[a-zA-Z_0-9]+)";
57
58 public static final String VALID_TABLE_QUALIFIER_REGEX =
59 "(?:[a-zA-Z_0-9][a-zA-Z_0-9-.]*)";
60
61
62 public static final String VALID_USER_TABLE_REGEX =
63 "(?:(?:(?:"+VALID_NAMESPACE_REGEX+"\\"+NAMESPACE_DELIM+")?)" +
64 "(?:"+VALID_TABLE_QUALIFIER_REGEX+"))";
65
66
67 public static final TableName ROOT_TABLE_NAME =
68 valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "root");
69
70
71 public static final TableName META_TABLE_NAME =
72 valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "meta");
73
74
75 public static final TableName NAMESPACE_TABLE_NAME =
76 valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "namespace");
77
78 private static final String OLD_META_STR = ".META.";
79 private static final String OLD_ROOT_STR = "-ROOT-";
80
81 private byte[] name;
82 private String nameAsString;
83 private byte[] namespace;
84 private String namespaceAsString;
85 private byte[] qualifier;
86 private String qualifierAsString;
87
88 private TableName() {}
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 public static byte [] isLegalFullyQualifiedTableName(final byte[] tableName) {
110 if (tableName == null || tableName.length <= 0) {
111 throw new IllegalArgumentException("Name is null or empty");
112 }
113 int namespaceDelimIndex = com.google.common.primitives.Bytes.lastIndexOf(tableName,
114 (byte) NAMESPACE_DELIM);
115 if (namespaceDelimIndex == 0 || namespaceDelimIndex == -1){
116 isLegalTableQualifierName(tableName);
117 } else {
118 isLegalNamespaceName(tableName, 0, namespaceDelimIndex);
119 isLegalTableQualifierName(tableName, namespaceDelimIndex + 1, tableName.length);
120 }
121 return tableName;
122 }
123
124 public static void isLegalTableQualifierName(final byte[] qualifierName){
125 isLegalTableQualifierName(qualifierName, 0, qualifierName.length);
126 }
127
128
129
130
131
132
133
134
135
136
137 public static void isLegalTableQualifierName(final byte[] qualifierName,
138 int start,
139 int end){
140 if(end - start < 1) {
141 throw new IllegalArgumentException("Table qualifier must not be empty");
142 }
143 if (qualifierName[start] == '.' || qualifierName[start] == '-') {
144 throw new IllegalArgumentException("Illegal first character <" + qualifierName[0] +
145 "> at 0. Namespaces can only start with alphanumeric " +
146 "characters': i.e. [a-zA-Z_0-9]: " + Bytes.toString(qualifierName));
147 }
148 for (int i = start; i < end; i++) {
149 if (Character.isLetterOrDigit(qualifierName[i]) ||
150 qualifierName[i] == '_' ||
151 qualifierName[i] == '-' ||
152 qualifierName[i] == '.') {
153 continue;
154 }
155 throw new IllegalArgumentException("Illegal character <" + qualifierName[i] +
156 "> at " + i + ". User-space table qualifiers can only contain " +
157 "'alphanumeric characters': i.e. [a-zA-Z_0-9-.]: " +
158 Bytes.toString(qualifierName, start, end));
159 }
160 }
161
162 public static void isLegalNamespaceName(byte[] namespaceName) {
163 isLegalNamespaceName(namespaceName, 0, namespaceName.length);
164 }
165
166
167
168
169
170
171
172 public static void isLegalNamespaceName(byte[] namespaceName, int offset, int length) {
173 for (int i = offset; i < length; i++) {
174 if (Character.isLetterOrDigit(namespaceName[i])|| namespaceName[i] == '_') {
175 continue;
176 }
177 throw new IllegalArgumentException("Illegal character <" + namespaceName[i] +
178 "> at " + i + ". Namespaces can only contain " +
179 "'alphanumeric characters': i.e. [a-zA-Z_0-9]: " + Bytes.toString(namespaceName,
180 offset, length));
181 }
182 }
183
184 public byte[] getName() {
185 return name;
186 }
187
188 public String getNameAsString() {
189 return nameAsString;
190 }
191
192 public byte[] getNamespace() {
193 return namespace;
194 }
195
196 public String getNamespaceAsString() {
197 return namespaceAsString;
198 }
199
200 public byte[] getQualifier() {
201 return qualifier;
202 }
203
204 public String getQualifierAsString() {
205 return qualifierAsString;
206 }
207
208 public byte[] toBytes() {
209 return name;
210 }
211
212 @Override
213 public String toString() {
214 return nameAsString;
215 }
216
217 public static TableName valueOf(byte[] namespace, byte[] qualifier) {
218 TableName ret = new TableName();
219 if(namespace == null || namespace.length < 1) {
220 namespace = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME;
221 }
222 ret.namespace = namespace;
223 ret.namespaceAsString = Bytes.toString(namespace);
224 ret.qualifier = qualifier;
225 ret.qualifierAsString = Bytes.toString(qualifier);
226
227 finishValueOf(ret);
228
229 return ret;
230 }
231
232 public static TableName valueOf(String namespaceAsString, String qualifierAsString) {
233 TableName ret = new TableName();
234 if(namespaceAsString == null || namespaceAsString.length() < 1) {
235 namespaceAsString = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR;
236 }
237 ret.namespaceAsString = namespaceAsString;
238 ret.namespace = Bytes.toBytes(namespaceAsString);
239 ret.qualifier = Bytes.toBytes(qualifierAsString);
240 ret.qualifierAsString = qualifierAsString;
241
242 finishValueOf(ret);
243
244 return ret;
245 }
246
247 private static void finishValueOf(TableName tableName) {
248 isLegalNamespaceName(tableName.namespace);
249 isLegalTableQualifierName(tableName.qualifier);
250
251 tableName.nameAsString =
252 createFullyQualified(tableName.namespaceAsString, tableName.qualifierAsString);
253 tableName.name = Bytes.toBytes(tableName.nameAsString);
254 }
255
256 public static TableName valueOf(byte[] name) {
257 return valueOf(Bytes.toString(name));
258 }
259
260 public static TableName valueOf(String name) {
261 if(name.equals(OLD_ROOT_STR)) {
262 throw new IllegalArgumentException(OLD_ROOT_STR + " has been deprecated.");
263 }
264 if(name.equals(OLD_META_STR)) {
265 throw new IllegalArgumentException(OLD_META_STR + " no longer exists. The table has been " +
266 "renamed to "+META_TABLE_NAME);
267 }
268
269 isLegalFullyQualifiedTableName(Bytes.toBytes(name));
270 int index = name.indexOf(NAMESPACE_DELIM);
271 if (index != -1) {
272 return TableName.valueOf(name.substring(0, index), name.substring(index + 1));
273 }
274 return TableName.valueOf(NamespaceDescriptor.DEFAULT_NAMESPACE.getName(), name);
275 }
276
277 private static String createFullyQualified(String namespace, String tableQualifier) {
278 if (namespace.equals(NamespaceDescriptor.DEFAULT_NAMESPACE.getName())) {
279 return tableQualifier;
280 }
281 return namespace+NAMESPACE_DELIM+tableQualifier;
282 }
283
284 @Override
285 public boolean equals(Object o) {
286 if (this == o) return true;
287 if (o == null || getClass() != o.getClass()) return false;
288
289 TableName tableName = (TableName) o;
290
291 if (!nameAsString.equals(tableName.nameAsString)) return false;
292
293 return true;
294 }
295
296 @Override
297 public int hashCode() {
298 int result = nameAsString.hashCode();
299 return result;
300 }
301
302 @Override
303 public int compareTo(TableName tableName) {
304 return this.nameAsString.compareTo(tableName.getNameAsString());
305 }
306 }