001: /*
002: * Portions Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * Licensed Materials - Property of IBM
028: * RMI-IIOP v1.0
029: * Copyright IBM Corp. 1998 1999 All Rights Reserved
030: *
031: */
032:
033: package sun.rmi.rmic.iiop;
034:
035: import java.util.Hashtable;
036:
037: /**
038: * A NameContext enables detection of strings which differ only
039: * in case.
040: *
041: * @version 1.0, 3/19/98
042: * @author Bryan Atsatt
043: */
044: class NameContext {
045:
046: private Hashtable table;
047: private boolean allowCollisions;
048:
049: /**
050: * Get a context for the given name. Name may be null, in
051: * which case this method will return the default context.
052: */
053: public static synchronized NameContext forName(String name,
054: boolean allowCollisions, BatchEnvironment env) {
055:
056: NameContext result = null;
057:
058: // Do we need to use the default context?
059:
060: if (name == null) {
061:
062: // Yes.
063:
064: name = "null";
065: }
066:
067: // Have we initialized our hashtable?
068:
069: if (env.nameContexts == null) {
070:
071: // Nope, so do it...
072:
073: env.nameContexts = new Hashtable();
074:
075: } else {
076:
077: // Yes, see if we already have the requested
078: // context...
079:
080: result = (NameContext) env.nameContexts.get(name);
081: }
082:
083: // Do we have the requested context?
084:
085: if (result == null) {
086:
087: // Nope, so create and add it...
088:
089: result = new NameContext(allowCollisions);
090:
091: env.nameContexts.put(name, result);
092: }
093:
094: return result;
095: }
096:
097: /**
098: * Construct a context.
099: * @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 \""
169: + value.name + "\"");
170: }
171: }
172: } else {
173:
174: // No, so add it...
175:
176: table.put(key, new Name(name, false));
177: }
178:
179: return null;
180: }
181:
182: /**
183: * Get a name from the context. If it has collisions, the name
184: * will be converted as specified in section 5.2.7.
185: */
186: public String get(String name) {
187:
188: Name it = (Name) table.get(name.toLowerCase());
189: String result = name;
190:
191: // Do we need to mangle it?
192:
193: if (it.collisions) {
194:
195: // Yep, so do it...
196:
197: int length = name.length();
198: boolean allLower = true;
199:
200: for (int i = 0; i < length; i++) {
201:
202: if (Character.isUpperCase(name.charAt(i))) {
203: result += "_";
204: result += i;
205: allLower = false;
206: }
207: }
208:
209: if (allLower) {
210: result += "_";
211: }
212: }
213:
214: return result;
215: }
216:
217: /**
218: * Remove all entries.
219: */
220: public void clear() {
221: table.clear();
222: }
223:
224: public class Name {
225: public String name;
226: public boolean collisions;
227:
228: public Name(String name, boolean collisions) {
229: this.name = name;
230: this.collisions = collisions;
231: }
232: }
233: }
|