aoqi@0: /* aoqi@0: * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: /* aoqi@0: * Licensed Materials - Property of IBM aoqi@0: * RMI-IIOP v1.0 aoqi@0: * Copyright IBM Corp. 1998 1999 All Rights Reserved aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: package sun.rmi.rmic.iiop; aoqi@0: aoqi@0: import java.util.Hashtable; aoqi@0: aoqi@0: /** aoqi@0: * A NameContext enables detection of strings which differ only aoqi@0: * in case. aoqi@0: * aoqi@0: * @author Bryan Atsatt aoqi@0: */ aoqi@0: class NameContext { aoqi@0: aoqi@0: private Hashtable table; aoqi@0: private boolean allowCollisions; aoqi@0: aoqi@0: /** aoqi@0: * Get a context for the given name. Name may be null, in aoqi@0: * which case this method will return the default context. aoqi@0: */ aoqi@0: public static synchronized NameContext forName (String name, aoqi@0: boolean allowCollisions, aoqi@0: BatchEnvironment env) { aoqi@0: aoqi@0: NameContext result = null; aoqi@0: aoqi@0: // Do we need to use the default context? aoqi@0: aoqi@0: if (name == null) { aoqi@0: aoqi@0: // Yes. aoqi@0: aoqi@0: name = "null"; aoqi@0: } aoqi@0: aoqi@0: // Have we initialized our hashtable? aoqi@0: aoqi@0: if (env.nameContexts == null) { aoqi@0: aoqi@0: // Nope, so do it... aoqi@0: aoqi@0: env.nameContexts = new Hashtable(); aoqi@0: aoqi@0: } else { aoqi@0: aoqi@0: // Yes, see if we already have the requested aoqi@0: // context... aoqi@0: aoqi@0: result = (NameContext) env.nameContexts.get(name); aoqi@0: } aoqi@0: aoqi@0: // Do we have the requested context? aoqi@0: aoqi@0: if (result == null) { aoqi@0: aoqi@0: // Nope, so create and add it... aoqi@0: aoqi@0: result = new NameContext(allowCollisions); aoqi@0: aoqi@0: env.nameContexts.put(name,result); aoqi@0: } aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Construct a context. aoqi@0: * @param allowCollisions true if case-sensitive name collisions aoqi@0: * are allowed, false if not. aoqi@0: */ aoqi@0: public NameContext (boolean allowCollisions) { aoqi@0: this.allowCollisions = allowCollisions; aoqi@0: table = new Hashtable(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Add a name to this context. If constructed with allowCollisions aoqi@0: * false and a collision occurs, this method will throw an exception aoqi@0: * in which the message contains the string: "name" and "collision". aoqi@0: */ aoqi@0: public void assertPut (String name) throws Exception { aoqi@0: aoqi@0: String message = add(name); aoqi@0: aoqi@0: if (message != null) { aoqi@0: throw new Exception(message); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Add a name to this context.. aoqi@0: */ aoqi@0: public void put (String name) { aoqi@0: aoqi@0: if (allowCollisions == false) { aoqi@0: throw new Error("Must use assertPut(name)"); aoqi@0: } aoqi@0: aoqi@0: add(name); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Add a name to this context. If constructed with allowCollisions aoqi@0: * false and a collision occurs, this method will return a message aoqi@0: * string, otherwise returns null. aoqi@0: */ aoqi@0: private String add (String name) { aoqi@0: aoqi@0: // First, create a key by converting name to lowercase... aoqi@0: aoqi@0: String key = name.toLowerCase(); aoqi@0: aoqi@0: // Does this key exist in the context? aoqi@0: aoqi@0: Name value = (Name) table.get(key); aoqi@0: aoqi@0: if (value != null) { aoqi@0: aoqi@0: // Yes, so they match if we ignore case. Do they match if aoqi@0: // we don't ignore case? aoqi@0: aoqi@0: if (!name.equals(value.name)) { aoqi@0: aoqi@0: // No, so this is a case-sensitive match. Are we aoqi@0: // supposed to allow this? aoqi@0: aoqi@0: if (allowCollisions) { aoqi@0: aoqi@0: // Yes, make sure it knows that it collides... aoqi@0: aoqi@0: value.collisions = true; aoqi@0: aoqi@0: } else { aoqi@0: aoqi@0: // No, so return a message string... aoqi@0: aoqi@0: return new String("\"" + name + "\" and \"" + value.name + "\""); aoqi@0: } aoqi@0: } aoqi@0: } else { aoqi@0: aoqi@0: // No, so add it... aoqi@0: aoqi@0: table.put(key,new Name(name,false)); aoqi@0: } aoqi@0: aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get a name from the context. If it has collisions, the name aoqi@0: * will be converted as specified in section 5.2.7. aoqi@0: */ aoqi@0: public String get (String name) { aoqi@0: aoqi@0: Name it = (Name) table.get(name.toLowerCase()); aoqi@0: String result = name; aoqi@0: aoqi@0: // Do we need to mangle it? aoqi@0: aoqi@0: if (it.collisions) { aoqi@0: aoqi@0: // Yep, so do it... aoqi@0: aoqi@0: int length = name.length(); aoqi@0: boolean allLower = true; aoqi@0: aoqi@0: for (int i = 0; i < length; i++) { aoqi@0: aoqi@0: if (Character.isUpperCase(name.charAt(i))) { aoqi@0: result += "_"; aoqi@0: result += i; aoqi@0: allLower = false; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: if (allLower) { aoqi@0: result += "_"; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Remove all entries. aoqi@0: */ aoqi@0: public void clear () { aoqi@0: table.clear(); aoqi@0: } aoqi@0: aoqi@0: public class Name { aoqi@0: public String name; aoqi@0: public boolean collisions; aoqi@0: aoqi@0: public Name (String name, boolean collisions) { aoqi@0: this.name = name; aoqi@0: this.collisions = collisions; aoqi@0: } aoqi@0: } aoqi@0: }