• 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 
21 import com.google.common.annotations.VisibleForTesting;
22 import com.google.common.base.Function;
23 import com.google.common.collect.Ordering;
24 import org.checkerframework.checker.nullness.compatqual.NullableDecl;
25 
26 /**
27  * Immutable representation of a file name. Used both for the name components of paths and as the
28  * keys for directory entries.
29  *
30  * <p>A name has both a display string (used in the {@code toString()} form of a {@code Path} as
31  * well as for {@code Path} equality and sort ordering) and a canonical string, which is used for
32  * determining equality of the name during file lookup.
33  *
34  * <p>Note: all factory methods return a constant name instance when given the original string "."
35  * or "..", ensuring that those names can be accessed statically elsewhere in the code while still
36  * being equal to any names created for those values, regardless of normalization settings.
37  *
38  * @author Colin Decker
39  */
40 final class Name {
41 
42   /** The empty name. */
43   static final Name EMPTY = new Name("", "");
44 
45   /** The name to use for a link from a directory to itself. */
46   public static final Name SELF = new Name(".", ".");
47 
48   /** The name to use for a link from a directory to its parent directory. */
49   public static final Name PARENT = new Name("..", "..");
50 
51   /** Creates a new name with no normalization done on the given string. */
52   @VisibleForTesting
simple(String name)53   static Name simple(String name) {
54     switch (name) {
55       case ".":
56         return SELF;
57       case "..":
58         return PARENT;
59       default:
60         return new Name(name, name);
61     }
62   }
63 
64   /**
65    * Creates a name with the given display representation and the given canonical representation.
66    */
create(String display, String canonical)67   public static Name create(String display, String canonical) {
68     return new Name(display, canonical);
69   }
70 
71   private final String display;
72   private final String canonical;
73 
Name(String display, String canonical)74   private Name(String display, String canonical) {
75     this.display = checkNotNull(display);
76     this.canonical = checkNotNull(canonical);
77   }
78 
79   @Override
equals(@ullableDecl Object obj)80   public boolean equals(@NullableDecl Object obj) {
81     if (obj instanceof Name) {
82       Name other = (Name) obj;
83       return canonical.equals(other.canonical);
84     }
85     return false;
86   }
87 
88   @Override
hashCode()89   public int hashCode() {
90     return Util.smearHash(canonical.hashCode());
91   }
92 
93   @Override
toString()94   public String toString() {
95     return display;
96   }
97 
98   /** Returns an ordering that orders names by their display representation. */
displayOrdering()99   public static Ordering<Name> displayOrdering() {
100     return DISPLAY_ORDERING;
101   }
102 
103   /** Returns an ordering that orders names by their canonical representation. */
canonicalOrdering()104   public static Ordering<Name> canonicalOrdering() {
105     return CANONICAL_ORDERING;
106   }
107 
108   private static final Ordering<Name> DISPLAY_ORDERING =
109       Ordering.natural()
110           .onResultOf(
111               new Function<Name, String>() {
112                 @Override
113                 public String apply(Name name) {
114                   return name.display;
115                 }
116               });
117 
118   private static final Ordering<Name> CANONICAL_ORDERING =
119       Ordering.natural()
120           .onResultOf(
121               new Function<Name, String>() {
122                 @Override
123                 public String apply(Name name) {
124                   return name.canonical;
125                 }
126               });
127 }
128