/* * 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]; } }