Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java')
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java93
1 files changed, 93 insertions, 0 deletions
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java
new file mode 100644
index 000000000..b76057dd5
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Xenos (Google) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.nd;
+
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.internal.core.nd.db.IndexException;
+
+/**
+ * Maps integer constants onto factories for {@link NdNode} objects.
+ */
+public class NdNodeTypeRegistry<R> {
+ private final Map<Short, ITypeFactory<? extends R>> types = new HashMap<>();
+ private final BitSet reserved = new BitSet();
+ private final Map<Class<?>, Short> registeredClasses = new HashMap<>();
+
+ /**
+ * Registers a class to be used with this node type registry. Note that if we ever want to stop registering a type
+ * name in the future, its fully-qualified class name should be passed to reserve(...) to prevent its hashfrom being
+ * reused in the future.
+ */
+ public <T extends R> void register(int typeId, ITypeFactory<T> toRegister) {
+ if ((typeId & 0xFFFF0000) != 0) {
+ throw new IllegalArgumentException("The typeId " + typeId + " does not fit within a short int"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ short shortTypeId = (short)typeId;
+ String fullyQualifiedClassName = toRegister.getElementClass().getName();
+
+ if (this.types.containsKey(typeId) || this.reserved.get(typeId)) {
+ throw new IllegalArgumentException(
+ "The type id " + typeId + " for class " + fullyQualifiedClassName + " is already in use."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ this.types.put(shortTypeId, toRegister);
+ this.registeredClasses.put(toRegister.getElementClass(), shortTypeId);
+ }
+
+ /**
+ * Reserves the given node class name, such that its hash cannot be used by any other node registered with
+ * "register". If we ever want to unregister a given Class from the type registry, its class name should be reserved
+ * using this method. Doing so will prevent its type ID from being reused by another future class.
+ */
+ public void reserve(short typeId) {
+ if (this.types.containsKey(typeId) || this.reserved.get(typeId)) {
+ throw new IllegalArgumentException("The type ID " + typeId + " is already in use"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ this.reserved.set(typeId);
+ }
+
+ /**
+ * Returns the class associated with the given type or null if the given type ID is not known
+ */
+ public ITypeFactory<? extends R> getClassForType(short type) {
+ return this.types.get(type);
+ }
+
+ public R createNode(Nd nd, long address, short nodeType) throws IndexException {
+ ITypeFactory<? extends R> typeFactory = this.types.get(nodeType);
+
+ return typeFactory.create(nd, address);
+ }
+
+ public short getTypeForClass(Class<? extends R> toQuery) {
+ Short classId = this.registeredClasses.get(toQuery);
+
+ if (classId == null) {
+ throw new IllegalArgumentException(toQuery.getName() + " was not registered as a node type"); //$NON-NLS-1$
+ }
+ return classId;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends R> ITypeFactory<T> getTypeFactory(short nodeType) {
+ ITypeFactory<T> result = (ITypeFactory<T>) this.types.get(nodeType);
+
+ if (result == null) {
+ throw new IllegalArgumentException("The node type " + nodeType //$NON-NLS-1$
+ + " is not registered with this database"); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+}

Back to the top