/******************************************************************************* * Copyright (c) 2012, 2014 Willink Transformations 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: * E.D.Willink - initial API and implementation *******************************************************************************/ package org.eclipse.ocl.pivot.internal.ids; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.ids.BindingsId; import org.eclipse.ocl.pivot.ids.ElementId; import org.eclipse.ocl.pivot.ids.EnumerationLiteralId; import org.eclipse.ocl.pivot.ids.IdManager; import org.eclipse.ocl.pivot.ids.OperationId; import org.eclipse.ocl.pivot.ids.ParametersId; import org.eclipse.ocl.pivot.ids.PropertyId; import org.eclipse.ocl.pivot.ids.TemplateParameterId; import org.eclipse.ocl.pivot.ids.TemplateableId; public abstract class AbstractTemplateableIdImpl<T extends TemplateableId> extends AbstractElementId implements TemplateableId { protected final @NonNull Integer hashCode; /** * Map from template bindings to the corresponding specialization. */ private @Nullable WeakHashMapOfWeakReference<BindingsId, T> specializations = null; protected final int templateParameters; protected AbstractTemplateableIdImpl(@NonNull Integer hashCode, int templateParameters) { this.hashCode = hashCode; this.templateParameters = templateParameters; } protected abstract @NonNull T createSpecializedId(@NonNull BindingsId templateBindings); public @NonNull EnumerationLiteralId getEnumerationLiteralId(@NonNull String name) { throw new UnsupportedOperationException(); // Only NestableTypeIds may have enumeration literals. } public @NonNull OperationId getOperationId(int templateParameters, @NonNull String name, @NonNull ParametersId parametersId) { throw new UnsupportedOperationException(); // Only NestableTypeIds may nest. } public @NonNull PropertyId getPropertyId(@NonNull String name) { throw new UnsupportedOperationException(); } @Override public @NonNull T getSpecializedId(@NonNull BindingsId templateBindings) { WeakHashMapOfWeakReference<BindingsId, T> specializations2 = specializations; if (specializations2 == null) { synchronized (this) { specializations2 = specializations; if (specializations2 == null) { specializations = specializations2 = new WeakHashMapOfWeakReference<BindingsId, T>() { @Override protected @NonNull T newId(@NonNull BindingsId templateBindings) { return createSpecializedId(templateBindings); } }; } } } return specializations2.getId(templateBindings); } public @NonNull T getSpecializedId(@NonNull ElementId... templateBindings) { assert templateBindings.length == templateParameters; return getSpecializedId(IdManager.getBindingsId(templateBindings)); } public @NonNull TemplateParameterId getTemplateParameterId(int index) { return IdManager.getTemplateParameterId(index); } @Override public int getTemplateParameters() { return templateParameters; } @Override public final int hashCode() { return hashCode; } }