/*******************************************************************************
* Copyright (c) 2013-2014 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.Map;
import org.rascalmpl.value.IAnnotatable;
import org.rascalmpl.value.IValue;
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 annotations to it.
*
* @param <T> the interface over which this annotation wrapper closes
*/
public abstract class AbstractDefaultAnnotatable<T extends IValue> implements IAnnotatable<T> {
protected final T content;
protected final ImmutableMap<String, IValue> annotations;
/**
* Creates an {@link IAnnotatable} view on {@literal content} with empty
* annotations.
*
* @param content
* is the wrapped object that supports annotations
*/
public AbstractDefaultAnnotatable(T content) {
this.content = content;
this.annotations = AbstractSpecialisedImmutableMap.mapOf();
}
/**
* Creates an {@link IAnnotatable} view on {@link #content} with already
* provided {@link #annotations}.
*
* @param content
* is the wrapped object that supports annotations
* @param annotations
* is the map of annotations associated to {@link #content}
*/
public AbstractDefaultAnnotatable(T content, ImmutableMap<String, IValue> annotations) {
this.content = content;
this.annotations = annotations;
}
/**
* Wraps {@link #content} with other annotations. This methods is mandatory
* because of PDB's immutable value nature: Once annotations 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 #annotations}
*/
protected abstract T wrap(final T content, final ImmutableMap<String, IValue> annotations);
@Override
public boolean hasAnnotations() {
return annotations.size() > 0;
}
@Override
public Map<String, IValue> getAnnotations() {
return annotations;
}
@Override
public T removeAnnotations() {
return content;
}
@Override
public boolean hasAnnotation(String label) throws FactTypeUseException {
return annotations.containsKey(label);
}
@Override
public IValue getAnnotation(String label) throws FactTypeUseException {
return annotations.get(label);
}
@Override
public T setAnnotation(String label, IValue newValue)
throws FactTypeUseException {
return wrap(content, annotations.__put(label, newValue));
}
@Override
public T removeAnnotation(String label) {
return wrap(content, annotations.__remove(label));
}
@Override
public T setAnnotations(Map<String, IValue> otherAnnotations) {
if (otherAnnotations.isEmpty())
return content;
return wrap(content, AbstractSpecialisedImmutableMap.mapOf(otherAnnotations));
}
@Override
public T joinAnnotations(Map<String, IValue> otherAnnotations) {
return wrap(content, annotations.__putAll(otherAnnotations));
}
@Override
public String toString() {
return content.toString();
}
// @Override
// public int hashCode() {
// // TODO
// }
//
// @Override
// public boolean equals(Object obj) {
// // TODO
// }
}