org.springsource.loaded.NameRegistry Maven / Gradle / Ivy
/*
* Copyright 2010-2012 VMware and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springsource.loaded;
/**
* Manages a mapping of names to numbers. The same number anywhere means the same name. This means that if some type
* a/b/C has been loaded in two places (by different classloaders), it will have the same number in both. Only one of
* those a/b/C types will be visible at the location in question, the tricky part could be working out which one (if
* classloaders are being naughty) but in theory the first time we get confused (due to finding the name twice), we can
* work out which one is right and use that mapping from then on.
*
* @author Andy Clement
* @since 0.8.1
*/
public class NameRegistry {
private static int nextTypeId = 0;
private static int size = 10;
private static String[] allocatedIds = new String[size];
private NameRegistry() {
}
/**
* Typically used by tests to ensure it looks like a fresh NameRegistry is being used.
*/
public static void reset() {
nextTypeId = 0;
size = 10;
allocatedIds = new String[size];
}
/**
* Return the id for a particular type. This method will not allocate a new id if the type is unknown, it will
* return -1 instead.
*
* @param slashedClassName a type name like java/lang/String
* @return the allocated ID for that type or -1 if unknown
*/
public static int getIdFor(String slashedClassName) {
assert Asserts.assertNotDotted(slashedClassName);
for (int i = 0; i < nextTypeId; i++) {
if (allocatedIds[i].equals(slashedClassName)) {
return i;
}
}
return -1;
}
/**
* Return the id for a particular type. This method will not allocate a new id if the type is unknown, it will
* return -1 instead.
*
* @param slashedClassName a type name like java/lang/String
* @return the allocated ID for that type or -1 if unknown
*/
public static int getIdOrAllocateFor(String slashedClassName) {
int id = getIdFor(slashedClassName);
if (id == -1) {
id = allocateId(slashedClassName);
}
return id;
}
private synchronized static int allocateId(String slashedClassName) {
// Check again, in case two threads passed the -1 check in the getIdOrAllocateFor method
int id = getIdFor(slashedClassName);
if (id == -1) {
id = nextTypeId;
if (nextTypeId >= allocatedIds.length) {
size = size + 10;
// need to make more room
String[] newAllocatedIds = new String[size];
System.arraycopy(allocatedIds, 0, newAllocatedIds, 0, allocatedIds.length);
allocatedIds = newAllocatedIds;
}
allocatedIds[id] = slashedClassName;
nextTypeId++; // increase at the end once the value has been set in the array
}
return id;
}
public static String getTypenameById(int typeId) {
if (typeId > size) {
return null;
}
return allocatedIds[typeId];
}
}