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