1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.graph.property.basic;
25
26 import java.io.InputStream;
27 import java.io.Reader;
28 import java.math.BigDecimal;
29 import java.net.URI;
30 import java.util.Calendar;
31 import java.util.Date;
32 import java.util.UUID;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35 import net.jcip.annotations.Immutable;
36 import org.modeshape.common.text.TextDecoder;
37 import org.modeshape.common.util.CheckArg;
38 import org.modeshape.graph.GraphI18n;
39 import org.modeshape.graph.property.Binary;
40 import org.modeshape.graph.property.DateTime;
41 import org.modeshape.graph.property.IoException;
42 import org.modeshape.graph.property.Name;
43 import org.modeshape.graph.property.NameFactory;
44 import org.modeshape.graph.property.NamespaceException;
45 import org.modeshape.graph.property.NamespaceRegistry;
46 import org.modeshape.graph.property.Path;
47 import org.modeshape.graph.property.PropertyType;
48 import org.modeshape.graph.property.Reference;
49 import org.modeshape.graph.property.ValueFactory;
50 import org.modeshape.graph.property.ValueFormatException;
51
52
53
54
55 @Immutable
56 public class NameValueFactory extends AbstractValueFactory<Name> implements NameFactory {
57
58
59 protected static final String FULLY_QUALFIED_NAME_PATTERN_STRING = "\\{([^}]*)\\}(.*)";
60 protected static final Pattern FULLY_QUALIFIED_NAME_PATTERN = Pattern.compile(FULLY_QUALFIED_NAME_PATTERN_STRING);
61
62
63 private static final String PREFIXED_NAME_PATTERN_STRING = "(([^:/]+):)?([^:]*)";
64 private static final Pattern PREFIXED_NAME_PATTERN = Pattern.compile(PREFIXED_NAME_PATTERN_STRING);
65
66 private static Name BLANK_NAME;
67 private static Name ANY_NAME;
68
69 private final NamespaceRegistry namespaceRegistry;
70
71 public NameValueFactory( NamespaceRegistry namespaceRegistry,
72 TextDecoder decoder,
73 ValueFactory<String> stringValueFactory ) {
74 super(PropertyType.NAME, decoder, stringValueFactory);
75 CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry");
76 this.namespaceRegistry = namespaceRegistry;
77 }
78
79
80
81
82 public Name create( String value ) {
83 return create(value, getDecoder());
84 }
85
86
87
88
89 public Name create( String value,
90 TextDecoder decoder ) {
91 if (value == null) return null;
92 if (decoder == null) decoder = getDecoder();
93 try {
94 if (value.length() == 0) {
95 if (BLANK_NAME == null) BLANK_NAME = new BasicName("", "");
96 return BLANK_NAME;
97 }
98 char firstChar = value.charAt(0);
99 if (value.length() == 1 && firstChar == '*') {
100 if (ANY_NAME == null) ANY_NAME = new BasicName("", "*");
101 return ANY_NAME;
102 }
103 if (firstChar != '{') {
104
105 Matcher matcher = PREFIXED_NAME_PATTERN.matcher(value);
106 if (matcher.matches()) {
107 String prefix = matcher.group(2);
108 String localName = matcher.group(3);
109
110 prefix = prefix == null ? "" : decoder.decode(prefix);
111 localName = decoder.decode(localName);
112
113 String namespaceUri = this.namespaceRegistry.getNamespaceForPrefix(prefix);
114
115 if (namespaceUri == null) {
116 throw new NamespaceException(GraphI18n.noNamespaceRegisteredForPrefix.text(prefix));
117 }
118 return new BasicName(namespaceUri, localName);
119 }
120 }
121
122 Matcher matcher = FULLY_QUALIFIED_NAME_PATTERN.matcher(value);
123 if (matcher.matches()) {
124 String namespaceUri = matcher.group(1);
125 String localName = matcher.group(2);
126
127 return create(namespaceUri, localName, decoder);
128 }
129 } catch (NamespaceException err) {
130 throw new ValueFormatException(value, getPropertyType(),
131 GraphI18n.errorConvertingType.text(String.class.getSimpleName(),
132 Name.class.getSimpleName(),
133 value), err);
134 }
135 throw new ValueFormatException(value, getPropertyType(), GraphI18n.errorConvertingType.text(String.class.getSimpleName(),
136 Name.class.getSimpleName(),
137 value));
138 }
139
140
141
142
143 public Name create( String namespaceUri,
144 String localName ) {
145 return create(namespaceUri, localName, getDecoder());
146 }
147
148
149
150
151 public Name create( String namespaceUri,
152 String localName,
153 TextDecoder decoder ) {
154 CheckArg.isNotEmpty(localName, "localName");
155 if (decoder == null) decoder = getDecoder();
156 namespaceUri = namespaceUri != null ? decoder.decode(namespaceUri.trim()) : null;
157 localName = decoder.decode(localName.trim());
158 return new BasicName(namespaceUri, localName);
159 }
160
161
162
163
164 public Name create( int value ) {
165 throw new ValueFormatException(value, getPropertyType(),
166 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
167 Integer.class.getSimpleName(),
168 value));
169 }
170
171
172
173
174 public Name create( long value ) {
175 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
176 Long.class.getSimpleName(),
177 value));
178 }
179
180
181
182
183 public Name create( boolean value ) {
184 throw new ValueFormatException(value, getPropertyType(),
185 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
186 Boolean.class.getSimpleName(),
187 value));
188 }
189
190
191
192
193 public Name create( float value ) {
194 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
195 Float.class.getSimpleName(),
196 value));
197 }
198
199
200
201
202 public Name create( double value ) {
203 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
204 Double.class.getSimpleName(),
205 value));
206 }
207
208
209
210
211 public Name create( BigDecimal value ) {
212 throw new ValueFormatException(value, getPropertyType(),
213 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
214 BigDecimal.class.getSimpleName(),
215 value));
216 }
217
218
219
220
221 public Name create( Calendar value ) {
222 throw new ValueFormatException(value, getPropertyType(),
223 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
224 Calendar.class.getSimpleName(),
225 value));
226 }
227
228
229
230
231 public Name create( Date value ) {
232 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
233 Date.class.getSimpleName(),
234 value));
235 }
236
237
238
239
240
241
242 public Name create( DateTime value ) throws ValueFormatException {
243 throw new ValueFormatException(value, getPropertyType(),
244 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
245 DateTime.class.getSimpleName(),
246 value));
247 }
248
249
250
251
252 public Name create( Name value ) {
253 return value;
254 }
255
256
257
258
259 public Name create( Path value ) {
260 if (value == null) return null;
261 if (!value.isAbsolute() && value.size() == 1) {
262
263 Path.Segment segment = value.getLastSegment();
264
265 if (!segment.hasIndex()) return segment.getName();
266 }
267 throw new ValueFormatException(value, getPropertyType(), GraphI18n.errorConvertingType.text(Path.class.getSimpleName(),
268 Name.class.getSimpleName(),
269 value));
270 }
271
272
273
274
275 public Name create( Path.Segment segment ) {
276 if (segment == null) return null;
277
278 if (!segment.hasIndex()) return segment.getName();
279 throw new ValueFormatException(segment, getPropertyType(),
280 GraphI18n.errorConvertingType.text(Path.Segment.class.getSimpleName(),
281 Name.class.getSimpleName(),
282 segment));
283 }
284
285
286
287
288 public Name create( Reference value ) {
289 throw new ValueFormatException(value, getPropertyType(),
290 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
291 Reference.class.getSimpleName(),
292 value));
293 }
294
295
296
297
298 public Name create( URI value ) {
299 if (value == null) return null;
300 String asciiString = value.toASCIIString();
301
302 if (asciiString.startsWith("./") && asciiString.length() > 2) {
303 asciiString = asciiString.substring(2);
304 }
305 if (asciiString.indexOf('/') == -1) {
306 return create(asciiString);
307 }
308 throw new ValueFormatException(value, getPropertyType(), GraphI18n.errorConvertingType.text(URI.class.getSimpleName(),
309 Path.class.getSimpleName(),
310 value));
311 }
312
313
314
315
316
317
318 public Name create( UUID value ) throws IoException {
319 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
320 UUID.class.getSimpleName(),
321 value));
322 }
323
324
325
326
327 public Name create( byte[] value ) {
328
329 return create(getStringValueFactory().create(value));
330 }
331
332
333
334
335
336
337 public Name create( Binary value ) throws ValueFormatException, IoException {
338
339 return create(getStringValueFactory().create(value));
340 }
341
342
343
344
345 public Name create( InputStream stream,
346 long approximateLength ) throws IoException {
347
348 return create(getStringValueFactory().create(stream, approximateLength));
349 }
350
351
352
353
354 public Name create( Reader reader,
355 long approximateLength ) throws IoException {
356
357 return create(getStringValueFactory().create(reader, approximateLength));
358 }
359
360
361
362
363
364
365
366
367 public NamespaceRegistry getNamespaceRegistry() {
368 return namespaceRegistry;
369 }
370
371
372
373
374 @Override
375 protected Name[] createEmptyArray( int length ) {
376 return new Name[length];
377 }
378 }