• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.jimfs;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.base.Preconditions.checkState;
21 
22 import com.google.common.base.MoreObjects;
23 import java.nio.file.FileAlreadyExistsException;
24 import java.nio.file.NoSuchFileException;
25 import java.nio.file.NotDirectoryException;
26 import java.nio.file.NotLinkException;
27 import java.nio.file.Path;
28 import java.util.Objects;
29 import org.checkerframework.checker.nullness.compatqual.NullableDecl;
30 
31 /**
32  * Entry in a directory, containing references to the directory itself, the file the entry links to
33  * and the name of the entry.
34  *
35  * <p>May also represent a non-existent entry if the name does not link to any file in the
36  * directory.
37  */
38 final class DirectoryEntry {
39 
40   private final Directory directory;
41   private final Name name;
42 
43   @NullableDecl private final File file;
44 
45   @NullableDecl DirectoryEntry next; // for use in Directory
46 
DirectoryEntry(Directory directory, Name name, @NullableDecl File file)47   DirectoryEntry(Directory directory, Name name, @NullableDecl File file) {
48     this.directory = checkNotNull(directory);
49     this.name = checkNotNull(name);
50     this.file = file;
51   }
52 
53   /** Returns {@code true} if and only if this entry represents an existing file. */
exists()54   public boolean exists() {
55     return file != null;
56   }
57 
58   /**
59    * Checks that this entry exists, throwing an exception if not.
60    *
61    * @return this
62    * @throws NoSuchFileException if this entry does not exist
63    */
requireExists(Path pathForException)64   public DirectoryEntry requireExists(Path pathForException) throws NoSuchFileException {
65     if (!exists()) {
66       throw new NoSuchFileException(pathForException.toString());
67     }
68     return this;
69   }
70 
71   /**
72    * Checks that this entry does not exist, throwing an exception if it does.
73    *
74    * @return this
75    * @throws FileAlreadyExistsException if this entry does not exist
76    */
requireDoesNotExist(Path pathForException)77   public DirectoryEntry requireDoesNotExist(Path pathForException)
78       throws FileAlreadyExistsException {
79     if (exists()) {
80       throw new FileAlreadyExistsException(pathForException.toString());
81     }
82     return this;
83   }
84 
85   /**
86    * Checks that this entry exists and links to a directory, throwing an exception if not.
87    *
88    * @return this
89    * @throws NoSuchFileException if this entry does not exist
90    * @throws NotDirectoryException if this entry does not link to a directory
91    */
requireDirectory(Path pathForException)92   public DirectoryEntry requireDirectory(Path pathForException)
93       throws NoSuchFileException, NotDirectoryException {
94     requireExists(pathForException);
95     if (!file().isDirectory()) {
96       throw new NotDirectoryException(pathForException.toString());
97     }
98     return this;
99   }
100 
101   /**
102    * Checks that this entry exists and links to a symbolic link, throwing an exception if not.
103    *
104    * @return this
105    * @throws NoSuchFileException if this entry does not exist
106    * @throws NotLinkException if this entry does not link to a symbolic link
107    */
requireSymbolicLink(Path pathForException)108   public DirectoryEntry requireSymbolicLink(Path pathForException)
109       throws NoSuchFileException, NotLinkException {
110     requireExists(pathForException);
111     if (!file().isSymbolicLink()) {
112       throw new NotLinkException(pathForException.toString());
113     }
114     return this;
115   }
116 
117   /** Returns the directory containing this entry. */
directory()118   public Directory directory() {
119     return directory;
120   }
121 
122   /** Returns the name of this entry. */
name()123   public Name name() {
124     return name;
125   }
126 
127   /**
128    * Returns the file this entry links to.
129    *
130    * @throws IllegalStateException if the file does not exist
131    */
file()132   public File file() {
133     checkState(exists());
134     return file;
135   }
136 
137   /** Returns the file this entry links to or {@code null} if the file does not exist */
138   @NullableDecl
fileOrNull()139   public File fileOrNull() {
140     return file;
141   }
142 
143   @Override
equals(Object obj)144   public boolean equals(Object obj) {
145     if (obj instanceof DirectoryEntry) {
146       DirectoryEntry other = (DirectoryEntry) obj;
147       return directory.equals(other.directory)
148           && name.equals(other.name)
149           && Objects.equals(file, other.file);
150     }
151     return false;
152   }
153 
154   @Override
hashCode()155   public int hashCode() {
156     return Objects.hash(directory, name, file);
157   }
158 
159   @Override
toString()160   public String toString() {
161     return MoreObjects.toStringHelper(this)
162         .add("directory", directory)
163         .add("name", name)
164         .add("file", file)
165         .toString();
166   }
167 }
168