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