/******************************************************************************* * Copyright (c) 2013 CWI * 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: * * * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI *******************************************************************************/ package org.rascalmpl.value.impl; import java.util.Collections; import java.util.Map; import java.util.Set; import org.rascalmpl.value.IValue; import org.rascalmpl.value.IWithKeywordParameters; import org.rascalmpl.value.exceptions.FactTypeUseException; import io.usethesource.capsule.AbstractSpecialisedImmutableMap; import io.usethesource.capsule.ImmutableMap; /** * A generic wrapper for an {@link IValue} that associates keyword parameters to it. * * @param <T> the interface over which this parameter wrapper closes */ public abstract class AbstractDefaultWithKeywordParameters<T extends IValue> implements IWithKeywordParameters<T> { protected final T content; protected final ImmutableMap<String, IValue> parameters; /** * Creates an {@link IWithKeywordParameters} view on {@link #content} with already * provided {@link #parameters}. * * @param content * is the wrapped object that supports annotations * @param parameters * is the map of annotations associated to {@link #content} */ public AbstractDefaultWithKeywordParameters(T content, ImmutableMap<String, IValue> parameters) { this.content = content; this.parameters = parameters; } /** * Wraps {@link #content} with other parameters. This methods is mandatory * because of PDB's immutable value nature: Once parameters are modified, a * new immutable view is returned. * * @param content * is the wrapped object that supports annotations * @param annotations * is the map of annotations associated to {@link #content} * @return a new representations of {@link #content} with associated * {@link #parameters} */ protected abstract T wrap(final T content, final ImmutableMap<String, IValue> parameters); @Override public String toString() { return content.toString(); } @Override public IValue getParameter(String label) throws FactTypeUseException { return parameters.get(label); } @Override public T setParameter(String label, IValue newValue) throws FactTypeUseException { return wrap(content, parameters.__put(label, newValue)); } @Override public T unsetParameter(String label) { ImmutableMap<String, IValue> removed = parameters.__remove(label); if (removed.size() == 0) { return content; } else { return wrap(content, removed); } } @Override public T unsetAll() { return content; } @Override public boolean hasParameter(String label) throws FactTypeUseException { return parameters.containsKey(label); } @Override public boolean hasParameters() { return parameters.size() > 0; } @Override public Set<String> getParameterNames() { return parameters.keySet(); } @Override public Map<String,IValue> getParameters() { return Collections.unmodifiableMap(parameters); } @Override public boolean equals(Object other) { if (!getClass().equals(other.getClass())) { return false; } AbstractDefaultWithKeywordParameters<? extends IValue> o = (AbstractDefaultWithKeywordParameters<?>) other; if (!content.isEqual(o.content)) { return false; } if (parameters.size() != o.parameters.size()) { return false; } for (String key : parameters.keySet()) { if (!getParameter(key).equals(o.getParameter(key))) { return false; } } return true; } @Override public <U extends IWithKeywordParameters<? extends IValue>> boolean equalParameters(U other) { if (!(other instanceof AbstractDefaultWithKeywordParameters<?>)) { return false; } AbstractDefaultWithKeywordParameters<? extends IValue> o = (AbstractDefaultWithKeywordParameters<?>) other; if (parameters.size() != o.parameters.size()) { return false; } for (String key : parameters.keySet()) { // TODO: isEqual should become equals when annotations have been removed. IValue parameter = getParameter(key); if (parameter == null && o.getParameter(key) != null) { return false; } else if (parameter != null && !parameter.isEqual(o.getParameter(key))) { return false; } } return true; } @Override public T setParameters(Map<String, IValue> params) { return wrap(content, AbstractSpecialisedImmutableMap.mapOf(params)); } }