001 /*
002 * JBoss DNA (http://www.jboss.org/dna)
003 * See the COPYRIGHT.txt file distributed with this work for information
004 * regarding copyright ownership. Some portions may be licensed
005 * to Red Hat, Inc. under one or more contributor license agreements.
006 * See the AUTHORS.txt file in the distribution for a full listing of
007 * individual contributors.
008 *
009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010 * is licensed to you under the terms of the GNU Lesser General Public License as
011 * published by the Free Software Foundation; either version 2.1 of
012 * the License, or (at your option) any later version.
013 *
014 * JBoss DNA is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this software; if not, write to the Free
021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023 */
024 package org.jboss.dna.graph.property.basic;
025
026 import java.io.InputStream;
027 import java.io.Reader;
028 import java.math.BigDecimal;
029 import java.net.URI;
030 import java.util.ArrayList;
031 import java.util.Calendar;
032 import java.util.Date;
033 import java.util.LinkedList;
034 import java.util.List;
035 import java.util.UUID;
036 import java.util.regex.Pattern;
037 import net.jcip.annotations.Immutable;
038 import org.jboss.dna.common.text.TextDecoder;
039 import org.jboss.dna.common.util.CheckArg;
040 import org.jboss.dna.graph.GraphI18n;
041 import org.jboss.dna.graph.property.Binary;
042 import org.jboss.dna.graph.property.DateTime;
043 import org.jboss.dna.graph.property.IoException;
044 import org.jboss.dna.graph.property.Name;
045 import org.jboss.dna.graph.property.Path;
046 import org.jboss.dna.graph.property.PathFactory;
047 import org.jboss.dna.graph.property.PropertyType;
048 import org.jboss.dna.graph.property.Reference;
049 import org.jboss.dna.graph.property.ValueFactory;
050 import org.jboss.dna.graph.property.ValueFormatException;
051 import org.jboss.dna.graph.property.Path.Segment;
052
053 /**
054 * The standard {@link ValueFactory} for {@link PropertyType#NAME} values.
055 *
056 * @author Randall Hauch
057 * @author John Verhaeg
058 */
059 @Immutable
060 public class PathValueFactory extends AbstractValueFactory<Path> implements PathFactory {
061
062 /**
063 * Regular expression used to identify the different segments in a path, using the standard '/' delimiter. The expression is
064 * simply:
065 *
066 * <pre>
067 * /
068 * </pre>
069 */
070 protected static final Pattern DELIMITER_PATTERN = Pattern.compile("/");
071
072 /**
073 * Regular expression used to identify the different parts of a segment. The expression is
074 *
075 * <pre>
076 * ([ˆ*:/\[\]|]+)(:([ˆ*:/\[\]|]+))?(\[(\d+)])?
077 * </pre>
078 *
079 * where the first part is accessed with group 1, the second part is accessed with group 3, and the index is accessed with
080 * group 5.
081 */
082 protected static final Pattern SEGMENT_PATTERN = Pattern.compile("([^:/]+)(:([^/\\[\\]]+))?(\\[(\\d+)])?");
083
084 private final ValueFactory<Name> nameValueFactory;
085
086 public PathValueFactory( TextDecoder decoder,
087 ValueFactory<String> stringValueFactory,
088 ValueFactory<Name> nameValueFactory ) {
089 super(PropertyType.PATH, decoder, stringValueFactory);
090 CheckArg.isNotNull(nameValueFactory, "nameValueFactory");
091 this.nameValueFactory = nameValueFactory;
092 }
093
094 /**
095 * @return nameValueFactory
096 */
097 protected ValueFactory<Name> getNameValueFactory() {
098 return this.nameValueFactory;
099 }
100
101 /**
102 * <p>
103 * {@inheritDoc}
104 * </p>
105 *
106 * @see org.jboss.dna.graph.property.PathFactory#createRootPath()
107 */
108 public Path createRootPath() {
109 return RootPath.INSTANCE;
110 }
111
112 /**
113 * {@inheritDoc}
114 */
115 public Path create( String value ) {
116 return create(value, getDecoder());
117 }
118
119 /**
120 * {@inheritDoc}
121 */
122 public Path create( final String value,
123 TextDecoder decoder ) {
124 if (value == null) return null;
125 String trimmedValue = value.trim();
126 int length = trimmedValue.length();
127 boolean absolute = false;
128 if (length == 0) {
129 return BasicPath.EMPTY_RELATIVE;
130 }
131 if (Path.DELIMITER_STR.equals(trimmedValue)) return RootPath.INSTANCE;
132 if (Path.SELF.equals(trimmedValue)) return BasicPath.SELF_PATH;
133 if (Path.PARENT.equals(trimmedValue)) return BasicPath.PARENT_PATH;
134
135 // Remove the leading delimiter ...
136 if (trimmedValue.charAt(0) == Path.DELIMITER) {
137 trimmedValue = length > 1 ? trimmedValue.substring(1) : "";
138 --length;
139 absolute = true;
140 }
141 // remove the trailing delimiter ...
142 if (length > 0 && trimmedValue.charAt(length - 1) == Path.DELIMITER) {
143 trimmedValue = length > 1 ? trimmedValue.substring(0, length - 1) : "";
144 length = trimmedValue.length();
145 }
146 if (length == 0) {
147 return RootPath.INSTANCE;
148 }
149
150 // Parse the path into its segments ...
151 List<Segment> segments = new ArrayList<Segment>();
152 String[] pathSegments = DELIMITER_PATTERN.split(trimmedValue);
153 if (pathSegments.length == 0) {
154 throw new ValueFormatException(value, getPropertyType(), GraphI18n.validPathMayNotContainEmptySegment.text(value));
155 }
156 if (decoder == null) decoder = getDecoder();
157 assert pathSegments.length != 0;
158 assert decoder != null;
159 for (String segment : pathSegments) {
160 assert segment != null;
161 segment = segment.trim();
162 if (segment.length() == 0) {
163 throw new ValueFormatException(value, getPropertyType(), GraphI18n.validPathMayNotContainEmptySegment.text(value));
164 }
165 // Create the name and add a segment with it ...
166 segments.add(createSegment(segment, decoder));
167 }
168
169 if (absolute && segments.size() == 1) {
170 // Special case of a single-segment name ...
171 return new ChildPath(RootPath.INSTANCE, segments.get(0));
172 }
173 // Create a path constructed from the supplied segments ...
174 return new BasicPath(segments, absolute);
175 }
176
177 /**
178 * {@inheritDoc}
179 */
180 public Path create( int value ) {
181 throw new ValueFormatException(value, getPropertyType(),
182 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
183 Integer.class.getSimpleName(),
184 value));
185 }
186
187 /**
188 * {@inheritDoc}
189 */
190 public Path create( long value ) {
191 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
192 Long.class.getSimpleName(),
193 value));
194 }
195
196 /**
197 * {@inheritDoc}
198 */
199 public Path create( boolean value ) {
200 throw new ValueFormatException(value, getPropertyType(),
201 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
202 Boolean.class.getSimpleName(),
203 value));
204 }
205
206 /**
207 * {@inheritDoc}
208 */
209 public Path create( float value ) {
210 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
211 Float.class.getSimpleName(),
212 value));
213 }
214
215 /**
216 * {@inheritDoc}
217 */
218 public Path create( double value ) {
219 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
220 Double.class.getSimpleName(),
221 value));
222 }
223
224 /**
225 * {@inheritDoc}
226 */
227 public Path create( BigDecimal value ) {
228 throw new ValueFormatException(value, getPropertyType(),
229 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
230 BigDecimal.class.getSimpleName(),
231 value));
232 }
233
234 /**
235 * {@inheritDoc}
236 */
237 public Path create( Calendar value ) {
238 throw new ValueFormatException(value, getPropertyType(),
239 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
240 Calendar.class.getSimpleName(),
241 value));
242 }
243
244 /**
245 * {@inheritDoc}
246 */
247 public Path create( Date value ) {
248 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
249 Date.class.getSimpleName(),
250 value));
251 }
252
253 /**
254 * {@inheritDoc}
255 *
256 * @see org.jboss.dna.graph.property.ValueFactory#create(org.jboss.dna.graph.property.DateTime)
257 */
258 public Path create( DateTime value ) throws ValueFormatException {
259 throw new ValueFormatException(value, getPropertyType(),
260 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
261 DateTime.class.getSimpleName(),
262 value));
263 }
264
265 /**
266 * {@inheritDoc}
267 */
268 public Path create( Name value ) {
269 if (value == null) return null;
270 try {
271 return new ChildPath(RootPath.INSTANCE, new BasicPathSegment(value));
272 } catch (IllegalArgumentException e) {
273 throw new ValueFormatException(value, getPropertyType(), e);
274 }
275 }
276
277 /**
278 * {@inheritDoc}
279 */
280 public Path create( Path value ) {
281 return value;
282 }
283
284 /**
285 * {@inheritDoc}
286 */
287 public Path createAbsolutePath( Name... segmentNames ) {
288 if (segmentNames == null || segmentNames.length == 0) return RootPath.INSTANCE;
289 List<Segment> segments = new ArrayList<Segment>(segmentNames.length);
290 for (Name segmentName : segmentNames) {
291 if (segmentName == null) {
292 CheckArg.containsNoNulls(segmentNames, "segment names");
293 }
294 segments.add(new BasicPathSegment(segmentName));
295 }
296 if (segments.size() == 1) {
297 // Special case of a single-segment name ...
298 return new ChildPath(RootPath.INSTANCE, segments.get(0));
299 }
300 return new BasicPath(segments, true);
301 }
302
303 /**
304 * {@inheritDoc}
305 */
306 public Path createAbsolutePath( Segment... segments ) {
307 if (segments == null || segments.length == 0) return RootPath.INSTANCE;
308 List<Segment> segmentsList = new ArrayList<Segment>(segments.length);
309 for (Segment segment : segments) {
310 if (segment == null) {
311 CheckArg.containsNoNulls(segments, "segments");
312 }
313 segmentsList.add(segment);
314 }
315 if (segmentsList.size() == 1) {
316 // Special case of a single-segment name ...
317 return new ChildPath(RootPath.INSTANCE, segmentsList.get(0));
318 }
319 return new BasicPath(segmentsList, true);
320 }
321
322 /**
323 * {@inheritDoc}
324 *
325 * @see org.jboss.dna.graph.property.PathFactory#createAbsolutePath(java.lang.Iterable)
326 */
327 public Path createAbsolutePath( Iterable<Segment> segments ) {
328 List<Segment> segmentsList = new LinkedList<Segment>();
329 for (Segment segment : segments) {
330 if (segment == null) {
331 CheckArg.containsNoNulls(segments, "segments");
332 }
333 segmentsList.add(segment);
334 }
335 if (segmentsList.isEmpty()) return RootPath.INSTANCE;
336 if (segmentsList.size() == 1) {
337 // Special case of a single-segment name ...
338 return new ChildPath(RootPath.INSTANCE, segmentsList.get(0));
339 }
340 return new BasicPath(segmentsList, true);
341 }
342
343 /**
344 * <p>
345 * {@inheritDoc}
346 * </p>
347 *
348 * @see org.jboss.dna.graph.property.PathFactory#createRelativePath()
349 */
350 public Path createRelativePath() {
351 return BasicPath.EMPTY_RELATIVE;
352 }
353
354 /**
355 * {@inheritDoc}
356 */
357 public Path createRelativePath( Name... segmentNames ) {
358 if (segmentNames == null || segmentNames.length == 0) return BasicPath.EMPTY_RELATIVE;
359 List<Segment> segments = new ArrayList<Segment>(segmentNames.length);
360 for (Name segmentName : segmentNames) {
361 if (segmentName == null) {
362 CheckArg.containsNoNulls(segmentNames, "segment names");
363 }
364 segments.add(new BasicPathSegment(segmentName));
365 }
366 return new BasicPath(segments, false);
367 }
368
369 /**
370 * {@inheritDoc}
371 */
372 public Path createRelativePath( Segment... segments ) {
373 if (segments == null || segments.length == 0) return BasicPath.EMPTY_RELATIVE;
374 List<Segment> segmentsList = new ArrayList<Segment>(segments.length);
375 for (Segment segment : segments) {
376 if (segment == null) {
377 CheckArg.containsNoNulls(segments, "segments");
378 }
379 segmentsList.add(segment);
380 }
381 return new BasicPath(segmentsList, false);
382 }
383
384 /**
385 * {@inheritDoc}
386 *
387 * @see org.jboss.dna.graph.property.PathFactory#createRelativePath(java.lang.Iterable)
388 */
389 public Path createRelativePath( Iterable<Segment> segments ) {
390 List<Segment> segmentsList = new LinkedList<Segment>();
391 for (Segment segment : segments) {
392 if (segment == null) {
393 CheckArg.containsNoNulls(segments, "segments");
394 }
395 segmentsList.add(segment);
396 }
397 if (segmentsList.isEmpty()) return BasicPath.EMPTY_RELATIVE;
398 return new BasicPath(segmentsList, false);
399 }
400
401 /**
402 * {@inheritDoc}
403 *
404 * @see org.jboss.dna.graph.property.PathFactory#create(org.jboss.dna.graph.property.Path, org.jboss.dna.graph.property.Path)
405 */
406 public Path create( Path parentPath,
407 Path childPath ) {
408 CheckArg.isNotNull(parentPath, "parent path");
409 CheckArg.isNotNull(childPath, "child path");
410 if (childPath.size() == 0) return parentPath;
411 if (parentPath.size() == 0) {
412 // Just need to return the child path, but it must be absolute if the parent is ...
413 if (childPath.isAbsolute() == parentPath.isAbsolute()) return childPath;
414 // They aren't the same absoluteness, so create a new one ...
415 return new BasicPath(childPath.getSegmentsList(), parentPath.isAbsolute());
416 }
417 List<Segment> segments = new ArrayList<Segment>(parentPath.size() + childPath.size());
418 for (Segment seg : parentPath) {
419 segments.add(seg);
420 }
421 for (Segment seg : childPath) {
422 segments.add(seg);
423 }
424 return new BasicPath(segments, parentPath.isAbsolute());
425 }
426
427 /**
428 * {@inheritDoc}
429 */
430 public Path create( Path parentPath,
431 Name segmentName,
432 int index ) {
433 CheckArg.isNotNull(parentPath, "parent path");
434 CheckArg.isNotNull(segmentName, "segment name");
435 return new ChildPath(parentPath, new BasicPathSegment(segmentName, index));
436 }
437
438 /**
439 * {@inheritDoc}
440 *
441 * @see org.jboss.dna.graph.property.PathFactory#create(org.jboss.dna.graph.property.Path, java.lang.String, int)
442 */
443 public Path create( Path parentPath,
444 String segmentName,
445 int index ) {
446 return create(parentPath, nameValueFactory.create(segmentName), index);
447 }
448
449 /**
450 * {@inheritDoc}
451 */
452 public Path create( Path parentPath,
453 Name... segmentNames ) {
454 CheckArg.isNotNull(parentPath, "parent path");
455 if (segmentNames == null || segmentNames.length == 0) return parentPath;
456 if (segmentNames.length == 1 && segmentNames[0] != null) {
457 return new ChildPath(parentPath, new BasicPathSegment(segmentNames[0]));
458 }
459
460 List<Segment> segments = new ArrayList<Segment>(parentPath.size() + 1);
461 segments.addAll(parentPath.getSegmentsList());
462 for (Name segmentName : segmentNames) {
463 if (segmentName == null) {
464 CheckArg.containsNoNulls(segmentNames, "segment names");
465 }
466 segments.add(new BasicPathSegment(segmentName));
467 }
468 return new BasicPath(segments, parentPath.isAbsolute());
469 }
470
471 /**
472 * {@inheritDoc}
473 */
474 public Path create( Path parentPath,
475 Segment... segments ) {
476 CheckArg.isNotNull(parentPath, "parent path");
477 if (segments == null || segments.length == 0) return RootPath.INSTANCE;
478 if (segments.length == 1 && segments[0] != null) {
479 return new ChildPath(parentPath, segments[0]);
480 }
481
482 List<Segment> segmentsList = new ArrayList<Segment>(parentPath.size() + 1);
483 segmentsList.addAll(parentPath.getSegmentsList());
484 for (Segment segment : segments) {
485 if (segment == null) {
486 CheckArg.containsNoNulls(segments, "segments");
487 }
488 segmentsList.add(segment);
489 }
490 return new BasicPath(segmentsList, parentPath.isAbsolute());
491 }
492
493 /**
494 * {@inheritDoc}
495 *
496 * @see org.jboss.dna.graph.property.PathFactory#create(org.jboss.dna.graph.property.Path, java.lang.Iterable)
497 */
498 public Path create( Path parentPath,
499 Iterable<Segment> segments ) {
500 CheckArg.isNotNull(parentPath, "parent path");
501
502 List<Segment> segmentsList = new LinkedList<Segment>();
503 segmentsList.addAll(parentPath.getSegmentsList());
504 for (Segment segment : segments) {
505 if (segment == null) {
506 CheckArg.containsNoNulls(segments, "segments");
507 }
508 segmentsList.add(segment);
509 }
510 if (segmentsList.isEmpty()) return RootPath.INSTANCE;
511 if (segmentsList.size() == 0) return new ChildPath(parentPath, segmentsList.get(0));
512 return new BasicPath(segmentsList, parentPath.isAbsolute());
513 }
514
515 /**
516 * {@inheritDoc}
517 *
518 * @see org.jboss.dna.graph.property.PathFactory#create(org.jboss.dna.graph.property.Path, java.lang.String)
519 */
520 public Path create( Path parentPath,
521 String subpath ) {
522 CheckArg.isNotNull(parentPath, "parentPath");
523 CheckArg.isNotNull(subpath, "subpath");
524 subpath = subpath.trim();
525 boolean singleChild = subpath.indexOf(Path.DELIMITER) == -1;
526 if (!singleChild && subpath.startsWith("./")) {
527 if (subpath.length() == 2) return parentPath; // self reference
528 // Remove the leading parent reference and try again to see if single child ...
529 subpath = subpath.substring(2);
530 singleChild = subpath.indexOf(Path.DELIMITER) == -1;
531 }
532 if (singleChild) {
533 try {
534 Path.Segment childSegment = createSegment(subpath);
535 return new ChildPath(parentPath, childSegment);
536 } catch (IllegalArgumentException t) {
537 // Catch and eat, letting the slower implementation catch anything ...
538 }
539 }
540 // It is a subpath with more than one segment, so create a relative path for the subpath ...
541 Path relativeSubpath = create(subpath);
542 return create(parentPath, relativeSubpath);
543
544 }
545
546 /**
547 * {@inheritDoc}
548 */
549 public Segment createSegment( Name segmentName ) {
550 CheckArg.isNotNull(segmentName, "segment name");
551 if (Path.SELF_NAME.equals(segmentName)) return Path.SELF_SEGMENT;
552 if (Path.PARENT_NAME.equals(segmentName)) return Path.PARENT_SEGMENT;
553 return new BasicPathSegment(segmentName);
554 }
555
556 /**
557 * {@inheritDoc}
558 */
559 public Segment createSegment( Name segmentName,
560 int index ) {
561 CheckArg.isNotNull(segmentName, "segment name");
562 if (Path.SELF_NAME.equals(segmentName)) return Path.SELF_SEGMENT;
563 if (Path.PARENT_NAME.equals(segmentName)) return Path.PARENT_SEGMENT;
564 return new BasicPathSegment(segmentName, index);
565 }
566
567 /**
568 * {@inheritDoc}
569 *
570 * @see org.jboss.dna.graph.property.PathFactory#createSegment(java.lang.String)
571 */
572 public Segment createSegment( String segmentName ) {
573 return createSegment(segmentName, getDecoder());
574 }
575
576 /**
577 * <p>
578 * {@inheritDoc}
579 * </p>
580 *
581 * @see org.jboss.dna.graph.property.PathFactory#createSegment(java.lang.String, org.jboss.dna.common.text.TextDecoder)
582 */
583 public Segment createSegment( String segmentName,
584 TextDecoder decoder ) {
585 CheckArg.isNotNull(segmentName, "segment name");
586 if (Path.SELF.equals(segmentName)) return Path.SELF_SEGMENT;
587 if (Path.PARENT.equals(segmentName)) return Path.PARENT_SEGMENT;
588 int startBracketNdx = segmentName.indexOf('[');
589 if (startBracketNdx < 0) {
590 return new BasicPathSegment(this.nameValueFactory.create(segmentName, decoder));
591 }
592 int endBracketNdx = segmentName.indexOf(']', startBracketNdx);
593 if (endBracketNdx < 0) {
594 throw new IllegalArgumentException(GraphI18n.missingEndBracketInSegmentName.text(segmentName));
595 }
596 String ndx = segmentName.substring(startBracketNdx + 1, endBracketNdx);
597 try {
598 return new BasicPathSegment(this.nameValueFactory.create(segmentName.substring(0, startBracketNdx), decoder),
599 Integer.parseInt(ndx));
600 } catch (NumberFormatException err) {
601 throw new ValueFormatException(segmentName, getPropertyType(), GraphI18n.invalidIndexInSegmentName.text(ndx,
602 segmentName));
603 }
604 }
605
606 /**
607 * {@inheritDoc}
608 */
609 public Segment createSegment( String segmentName,
610 int index ) {
611 CheckArg.isNotNull(segmentName, "segment name");
612 if (Path.SELF.equals(segmentName)) return Path.SELF_SEGMENT;
613 if (Path.PARENT.equals(segmentName)) return Path.PARENT_SEGMENT;
614 return new BasicPathSegment(this.nameValueFactory.create(segmentName), index);
615 }
616
617 /**
618 * {@inheritDoc}
619 */
620 public Path create( Reference value ) {
621 throw new ValueFormatException(value, getPropertyType(),
622 GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
623 Reference.class.getSimpleName(),
624 value));
625 }
626
627 /**
628 * {@inheritDoc}
629 */
630 public Path create( URI value ) {
631 if (value == null) return null;
632 String asciiString = value.toASCIIString();
633 // Remove any leading "./" ...
634 if (asciiString.startsWith("./") && asciiString.length() > 2) {
635 asciiString = asciiString.substring(2);
636 }
637 if (asciiString.indexOf('/') == -1) {
638 return create(asciiString);
639 }
640 throw new ValueFormatException(value, getPropertyType(), GraphI18n.errorConvertingType.text(URI.class.getSimpleName(),
641 Path.class.getSimpleName(),
642 value));
643 }
644
645 /**
646 * {@inheritDoc}
647 *
648 * @see org.jboss.dna.graph.property.ValueFactory#create(java.util.UUID)
649 */
650 public Path create( UUID value ) {
651 throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(),
652 UUID.class.getSimpleName(),
653 value));
654 }
655
656 /**
657 * {@inheritDoc}
658 */
659 public Path create( byte[] value ) {
660 // First attempt to create a string from the value, then a long from the string ...
661 return create(getStringValueFactory().create(value));
662 }
663
664 /**
665 * {@inheritDoc}
666 *
667 * @see org.jboss.dna.graph.property.ValueFactory#create(org.jboss.dna.graph.property.Binary)
668 */
669 public Path create( Binary value ) throws ValueFormatException, IoException {
670 // First create a string and then create the boolean from the string value ...
671 return create(getStringValueFactory().create(value));
672 }
673
674 /**
675 * {@inheritDoc}
676 */
677 public Path create( InputStream stream,
678 long approximateLength ) throws IoException {
679 // First attempt to create a string from the value, then a double from the string ...
680 return create(getStringValueFactory().create(stream, approximateLength));
681 }
682
683 /**
684 * {@inheritDoc}
685 */
686 public Path create( Reader reader,
687 long approximateLength ) throws IoException {
688 // First attempt to create a string from the value, then a double from the string ...
689 return create(getStringValueFactory().create(reader, approximateLength));
690 }
691
692 /**
693 * {@inheritDoc}
694 */
695 @Override
696 protected Path[] createEmptyArray( int length ) {
697 return new Path[length];
698 }
699
700 }