NameContext.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26/* 27 * Licensed Materials - Property of IBM 28 * RMI-IIOP v1.0 29 * Copyright IBM Corp. 1998 1999 All Rights Reserved 30 * 31 */ 32 33package sun.rmi.rmic.iiop; 34 35import java.util.Hashtable; 36 37/** 38 * A NameContext enables detection of strings which differ only 39 * in case. 40 * 41 * @author Bryan Atsatt 42 */ 43class NameContext { 44 45 private Hashtable table; 46 private boolean allowCollisions; 47 48 /** 49 * Get a context for the given name. Name may be null, in 50 * which case this method will return the default context. 51 */ 52 public static synchronized NameContext forName (String name, 53 boolean allowCollisions, 54 BatchEnvironment env) { 55 56 NameContext result = null; 57 58 // Do we need to use the default context? 59 60 if (name == null) { 61 62 // Yes. 63 64 name = "null"; 65 } 66 67 // Have we initialized our hashtable? 68 69 if (env.nameContexts == null) { 70 71 // Nope, so do it... 72 73 env.nameContexts = new Hashtable(); 74 75 } else { 76 77 // Yes, see if we already have the requested 78 // context... 79 80 result = (NameContext) env.nameContexts.get(name); 81 } 82 83 // Do we have the requested context? 84 85 if (result == null) { 86 87 // Nope, so create and add it... 88 89 result = new NameContext(allowCollisions); 90 91 env.nameContexts.put(name,result); 92 } 93 94 return result; 95 } 96 97 /** 98 * Construct a context. 99 * @param allowCollisions true if case-sensitive name collisions 100 * are allowed, false if not. 101 */ 102 public NameContext (boolean allowCollisions) { 103 this.allowCollisions = allowCollisions; 104 table = new Hashtable(); 105 } 106 107 /** 108 * Add a name to this context. If constructed with allowCollisions 109 * false and a collision occurs, this method will throw an exception 110 * in which the message contains the string: "name" and "collision". 111 */ 112 public void assertPut (String name) throws Exception { 113 114 String message = add(name); 115 116 if (message != null) { 117 throw new Exception(message); 118 } 119 } 120 121 /** 122 * Add a name to this context.. 123 */ 124 public void put (String name) { 125 126 if (allowCollisions == false) { 127 throw new Error("Must use assertPut(name)"); 128 } 129 130 add(name); 131 } 132 133 /** 134 * Add a name to this context. If constructed with allowCollisions 135 * false and a collision occurs, this method will return a message 136 * string, otherwise returns null. 137 */ 138 private String add (String name) { 139 140 // First, create a key by converting name to lowercase... 141 142 String key = name.toLowerCase(); 143 144 // Does this key exist in the context? 145 146 Name value = (Name) table.get(key); 147 148 if (value != null) { 149 150 // Yes, so they match if we ignore case. Do they match if 151 // we don't ignore case? 152 153 if (!name.equals(value.name)) { 154 155 // No, so this is a case-sensitive match. Are we 156 // supposed to allow this? 157 158 if (allowCollisions) { 159 160 // Yes, make sure it knows that it collides... 161 162 value.collisions = true; 163 164 } else { 165 166 // No, so return a message string... 167 168 return new String("\"" + name + "\" and \"" + value.name + "\""); 169 } 170 } 171 } else { 172 173 // No, so add it... 174 175 table.put(key,new Name(name,false)); 176 } 177 178 return null; 179 } 180 181 /** 182 * Get a name from the context. If it has collisions, the name 183 * will be converted as specified in section 5.2.7. 184 */ 185 public String get (String name) { 186 187 Name it = (Name) table.get(name.toLowerCase()); 188 String result = name; 189 190 // Do we need to mangle it? 191 192 if (it.collisions) { 193 194 // Yep, so do it... 195 196 int length = name.length(); 197 boolean allLower = true; 198 199 for (int i = 0; i < length; i++) { 200 201 if (Character.isUpperCase(name.charAt(i))) { 202 result += "_"; 203 result += i; 204 allLower = false; 205 } 206 } 207 208 if (allLower) { 209 result += "_"; 210 } 211 } 212 213 return result; 214 } 215 216 /** 217 * Remove all entries. 218 */ 219 public void clear () { 220 table.clear(); 221 } 222 223 public class Name { 224 public String name; 225 public boolean collisions; 226 227 public Name (String name, boolean collisions) { 228 this.name = name; 229 this.collisions = collisions; 230 } 231 } 232} 233