38 39 final class JrtPath implements Path { 40 41 private final JrtFileSystem jrtfs; 42 private final byte[] path; 43 private volatile int[] offsets; 44 private int hashcode = 0; // cached hashcode (created lazily) 45 46 JrtPath(JrtFileSystem jrtfs, byte[] path) { 47 this(jrtfs, path, false); 48 } 49 50 JrtPath(JrtFileSystem jrtfs, byte[] path, boolean normalized) { 51 this.jrtfs = jrtfs; 52 if (normalized) 53 this.path = path; 54 else 55 this.path = normalize(path); 56 } 57 58 @Override 59 public JrtPath getRoot() { 60 if (this.isAbsolute()) 61 return jrtfs.getRootPath(); 62 else 63 return null; 64 } 65 66 @Override 67 public Path getFileName() { 68 initOffsets(); 69 int count = offsets.length; 70 if (count == 0) 71 return null; // no elements so no name 72 if (count == 1 && path[0] != '/') 73 return this; 74 int lastOffset = offsets[count-1]; 75 int len = path.length - lastOffset; 76 byte[] result = new byte[len]; 77 System.arraycopy(path, lastOffset, result, 0, len); 123 endIndex > offsets.length || 124 beginIndex >= endIndex) 125 throw new IllegalArgumentException(); 126 127 // starting offset and length 128 int begin = offsets[beginIndex]; 129 int len; 130 if (endIndex == offsets.length) 131 len = path.length - begin; 132 else 133 len = offsets[endIndex] - begin - 1; 134 // construct result 135 byte[] result = new byte[len]; 136 System.arraycopy(path, begin, result, 0, len); 137 return new JrtPath(jrtfs, result); 138 } 139 140 @Override 141 public JrtPath toRealPath(LinkOption... options) throws IOException { 142 JrtPath realPath = new JrtPath(jrtfs, getResolvedPath()).toAbsolutePath(); 143 realPath.checkAccess(); 144 return realPath; 145 } 146 147 boolean isHidden() { 148 return false; 149 } 150 151 @Override 152 public JrtPath toAbsolutePath() { 153 if (isAbsolute()) { 154 return this; 155 } else { 156 //add / bofore the existing path 157 byte[] tmp = new byte[path.length + 1]; 158 tmp[0] = '/'; 159 System.arraycopy(path, 0, tmp, 1, path.length); 160 return (JrtPath) new JrtPath(jrtfs, tmp).normalize(); 161 } 162 } 163 164 @Override 165 public URI toUri() { 166 try { 621 throw new UnsupportedOperationException("'" + opt + "' not allowed"); 622 } 623 } 624 return jrtfs.newInputStream(getResolvedPath()); 625 } 626 627 DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter) 628 throws IOException 629 { 630 return new JrtDirectoryStream(this, filter); 631 } 632 633 void delete() throws IOException { 634 jrtfs.deleteFile(getResolvedPath(), true); 635 } 636 637 void deleteIfExists() throws IOException { 638 jrtfs.deleteFile(getResolvedPath(), false); 639 } 640 641 JrtFileAttributes getAttributes() throws IOException 642 { 643 JrtFileAttributes zfas = jrtfs.getFileAttributes(getResolvedPath()); 644 if (zfas == null) 645 throw new NoSuchFileException(toString()); 646 return zfas; 647 } 648 649 void setAttribute(String attribute, Object value, LinkOption... options) 650 throws IOException 651 { 652 String type; 653 String attr; 654 int colonPos = attribute.indexOf(':'); 655 if (colonPos == -1) { 656 type = "basic"; 657 attr = attribute; 658 } else { 659 type = attribute.substring(0, colonPos++); 660 attr = attribute.substring(colonPos); 661 } 662 JrtFileAttributeView view = JrtFileAttributeView.get(this, type); 663 if (view == null) 664 throw new UnsupportedOperationException("view <" + view + "> is not supported"); 665 view.setAttribute(attr, value); 666 } 667 668 void setTimes(FileTime mtime, FileTime atime, FileTime ctime) 669 throws IOException 670 { 671 jrtfs.setTimes(getResolvedPath(), mtime, atime, ctime); 672 } 673 674 Map<String, Object> readAttributes(String attributes, LinkOption... options) 675 throws IOException 676 677 { 678 String view; 679 String attrs; 680 int colonPos = attributes.indexOf(':'); 681 if (colonPos == -1) { 682 view = "basic"; 683 attrs = attributes; 684 } else { 685 view = attributes.substring(0, colonPos++); 686 attrs = attributes.substring(colonPos); 687 } 688 JrtFileAttributeView jrtfv = JrtFileAttributeView.get(this, view); 689 if (jrtfv == null) { 690 throw new UnsupportedOperationException("view not supported"); 691 } 692 return jrtfv.readAttributes(attrs); 693 } 694 695 FileStore getFileStore() throws IOException { 696 // each JrtFileSystem only has one root (as requested for now) 697 if (exists()) 698 return jrtfs.getFileStore(this); 699 throw new NoSuchFileException(JrtFileSystem.getString(path)); 700 } 701 702 boolean isSameFile(Path other) throws IOException { 703 if (this.equals(other)) 704 return true; 705 if (other == null || 706 this.getFileSystem() != other.getFileSystem()) 707 return false; 708 this.checkAccess(); 709 ((JrtPath)other).checkAccess(); 710 return Arrays.equals(this.getResolvedPath(), 711 ((JrtPath)other).getResolvedPath()); 712 } 713 714 SeekableByteChannel newByteChannel(Set<? extends OpenOption> options, 715 FileAttribute<?>... attrs) 716 throws IOException 717 { 718 return jrtfs.newByteChannel(getResolvedPath(), options, attrs); 719 } 720 721 722 FileChannel newFileChannel(Set<? extends OpenOption> options, 723 FileAttribute<?>... attrs) 724 throws IOException 725 { 726 return jrtfs.newFileChannel(getResolvedPath(), options, attrs); 727 } 728 729 void checkAccess(AccessMode... modes) throws IOException { 730 boolean w = false; 731 boolean x = false; | 38 39 final class JrtPath implements Path { 40 41 private final JrtFileSystem jrtfs; 42 private final byte[] path; 43 private volatile int[] offsets; 44 private int hashcode = 0; // cached hashcode (created lazily) 45 46 JrtPath(JrtFileSystem jrtfs, byte[] path) { 47 this(jrtfs, path, false); 48 } 49 50 JrtPath(JrtFileSystem jrtfs, byte[] path, boolean normalized) { 51 this.jrtfs = jrtfs; 52 if (normalized) 53 this.path = path; 54 else 55 this.path = normalize(path); 56 } 57 58 byte[] getName() { 59 return path; 60 } 61 62 @Override 63 public JrtPath getRoot() { 64 if (this.isAbsolute()) 65 return jrtfs.getRootPath(); 66 else 67 return null; 68 } 69 70 @Override 71 public Path getFileName() { 72 initOffsets(); 73 int count = offsets.length; 74 if (count == 0) 75 return null; // no elements so no name 76 if (count == 1 && path[0] != '/') 77 return this; 78 int lastOffset = offsets[count-1]; 79 int len = path.length - lastOffset; 80 byte[] result = new byte[len]; 81 System.arraycopy(path, lastOffset, result, 0, len); 127 endIndex > offsets.length || 128 beginIndex >= endIndex) 129 throw new IllegalArgumentException(); 130 131 // starting offset and length 132 int begin = offsets[beginIndex]; 133 int len; 134 if (endIndex == offsets.length) 135 len = path.length - begin; 136 else 137 len = offsets[endIndex] - begin - 1; 138 // construct result 139 byte[] result = new byte[len]; 140 System.arraycopy(path, begin, result, 0, len); 141 return new JrtPath(jrtfs, result); 142 } 143 144 @Override 145 public JrtPath toRealPath(LinkOption... options) throws IOException { 146 JrtPath realPath = new JrtPath(jrtfs, getResolvedPath()).toAbsolutePath(); 147 realPath = JrtFileSystem.followLinks(options)? jrtfs.resolveLink(this) : realPath; 148 realPath.checkAccess(); 149 return realPath; 150 } 151 152 JrtPath readSymbolicLink() throws IOException { 153 if (! jrtfs.isLink(this)) { 154 throw new IOException("not a symbolic link"); 155 } 156 157 return jrtfs.resolveLink(this); 158 } 159 160 boolean isHidden() { 161 return false; 162 } 163 164 @Override 165 public JrtPath toAbsolutePath() { 166 if (isAbsolute()) { 167 return this; 168 } else { 169 //add / bofore the existing path 170 byte[] tmp = new byte[path.length + 1]; 171 tmp[0] = '/'; 172 System.arraycopy(path, 0, tmp, 1, path.length); 173 return (JrtPath) new JrtPath(jrtfs, tmp).normalize(); 174 } 175 } 176 177 @Override 178 public URI toUri() { 179 try { 634 throw new UnsupportedOperationException("'" + opt + "' not allowed"); 635 } 636 } 637 return jrtfs.newInputStream(getResolvedPath()); 638 } 639 640 DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter) 641 throws IOException 642 { 643 return new JrtDirectoryStream(this, filter); 644 } 645 646 void delete() throws IOException { 647 jrtfs.deleteFile(getResolvedPath(), true); 648 } 649 650 void deleteIfExists() throws IOException { 651 jrtfs.deleteFile(getResolvedPath(), false); 652 } 653 654 JrtFileAttributes getAttributes(LinkOption... options) throws IOException 655 { 656 JrtFileAttributes zfas = jrtfs.getFileAttributes(getResolvedPath(), options); 657 if (zfas == null) 658 throw new NoSuchFileException(toString()); 659 return zfas; 660 } 661 662 void setAttribute(String attribute, Object value, LinkOption... options) 663 throws IOException 664 { 665 String type; 666 String attr; 667 int colonPos = attribute.indexOf(':'); 668 if (colonPos == -1) { 669 type = "basic"; 670 attr = attribute; 671 } else { 672 type = attribute.substring(0, colonPos++); 673 attr = attribute.substring(colonPos); 674 } 675 JrtFileAttributeView view = JrtFileAttributeView.get(this, type, options); 676 if (view == null) 677 throw new UnsupportedOperationException("view <" + view + "> is not supported"); 678 view.setAttribute(attr, value); 679 } 680 681 void setTimes(FileTime mtime, FileTime atime, FileTime ctime) 682 throws IOException 683 { 684 jrtfs.setTimes(getResolvedPath(), mtime, atime, ctime); 685 } 686 687 Map<String, Object> readAttributes(String attributes, LinkOption... options) 688 throws IOException 689 690 { 691 String view; 692 String attrs; 693 int colonPos = attributes.indexOf(':'); 694 if (colonPos == -1) { 695 view = "basic"; 696 attrs = attributes; 697 } else { 698 view = attributes.substring(0, colonPos++); 699 attrs = attributes.substring(colonPos); 700 } 701 JrtFileAttributeView jrtfv = JrtFileAttributeView.get(this, view, options); 702 if (jrtfv == null) { 703 throw new UnsupportedOperationException("view not supported"); 704 } 705 return jrtfv.readAttributes(attrs); 706 } 707 708 FileStore getFileStore() throws IOException { 709 // each JrtFileSystem only has one root (as requested for now) 710 if (exists()) 711 return jrtfs.getFileStore(this); 712 throw new NoSuchFileException(JrtFileSystem.getString(path)); 713 } 714 715 boolean isSameFile(Path other) throws IOException { 716 if (this.equals(other)) 717 return true; 718 if (other == null || 719 this.getFileSystem() != other.getFileSystem()) 720 return false; 721 this.checkAccess(); 722 JrtPath path = (JrtPath)other; 723 path.checkAccess(); 724 return Arrays.equals(this.getResolvedPath(), path.getResolvedPath()) || 725 jrtfs.isSameFile(this, (JrtPath)other); 726 } 727 728 SeekableByteChannel newByteChannel(Set<? extends OpenOption> options, 729 FileAttribute<?>... attrs) 730 throws IOException 731 { 732 return jrtfs.newByteChannel(getResolvedPath(), options, attrs); 733 } 734 735 736 FileChannel newFileChannel(Set<? extends OpenOption> options, 737 FileAttribute<?>... attrs) 738 throws IOException 739 { 740 return jrtfs.newFileChannel(getResolvedPath(), options, attrs); 741 } 742 743 void checkAccess(AccessMode... modes) throws IOException { 744 boolean w = false; 745 boolean x = false; |