package org.swellrt.model.unmutable;
import org.swellrt.model.ReadableBoolean;
import org.swellrt.model.ReadableMap;
import org.swellrt.model.ReadableNumber;
import org.swellrt.model.ReadableType;
import org.swellrt.model.ReadableTypeVisitable;
import org.swellrt.model.ReadableTypeVisitor;
import org.swellrt.model.adt.UnmutableBasicMap;
import org.swellrt.model.adt.UnmutableElementList;
import org.swellrt.model.generic.MapType;
import org.swellrt.model.generic.ValuesContainer;
import org.waveprotocol.wave.model.document.Doc;
import org.waveprotocol.wave.model.document.Doc.E;
import org.waveprotocol.wave.model.document.Document;
import org.waveprotocol.wave.model.document.util.DocHelper;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class UnmutableMap implements ReadableMap, ReadableTypeVisitable {
/**
* Adapt doc-based map elements to ReadableType's
*
*/
public static class ReadableMapElementAdapter implements
UnmutableBasicMap.ElementAdapter<String, ReadableType> {
private final Document document;
private final UnmutableElementList<String, Void> values;
private final UnmutableModel model;
public ReadableMapElementAdapter(UnmutableModel model, Document document,
UnmutableElementList<String, Void> values) {
this.document = document;
this.values = values;
this.model = model;
}
@Override
public Entry<String, ReadableType> fromElement(E element) {
final String key = document.getAttribute(element, "k");
final String value = document.getAttribute(element, "v");
return new Map.Entry<String, ReadableType>() {
@Override
public String getKey() {
return key;
}
@Override
public ReadableType getValue() {
return UnmutableTypeFactory.deserialize(model, values, value);
}
@Override
public ReadableType setValue(ReadableType value) {
return null;
}
};
}
};
public static UnmutableMap deserialize(UnmutableModel model, String substrateDocumentId) {
final Document document = model.getDocument(substrateDocumentId);
// Ignore on blips with no content
if (document == null) return null;
Doc.E eltMap = DocHelper.getElementWithTagName(document, MapType.TAG_MAP);
Doc.E eltValues = DocHelper.getElementWithTagName(document, ValuesContainer.TAG_VALUES);
@SuppressWarnings("unchecked")
UnmutableElementList<String, Void> values =
(UnmutableElementList<String, Void>) UnmutableElementList.create(
new UnmutableElementList.ElementAdapter<String>() {
@Override
public String fromElement(E element) {
return document.getAttribute(element, "v");
}
}, eltValues, document);
@SuppressWarnings("unchecked")
UnmutableBasicMap<String, ReadableType> map =
(UnmutableBasicMap<String, ReadableType>) UnmutableBasicMap.create(
new ReadableMapElementAdapter(model, document, values), eltMap, document);
return new UnmutableMap(map, values);
}
private final UnmutableBasicMap<String, ReadableType> docBasedMap;
private final UnmutableElementList<String, Void> values;
private UnmutableMap(UnmutableBasicMap<String, ReadableType> map,
UnmutableElementList<String, Void> values) {
this.docBasedMap = map;
this.values = values;
}
@Override
public void accept(ReadableTypeVisitor visitor) {
visitor.visit(this);
}
@Override
public ReadableType get(String key) {
return docBasedMap.get(key);
}
@Override
public Set<String> keySet() {
return docBasedMap.keySet();
}
@Override
public boolean hasKey(String key) {
return docBasedMap.keySet().contains(key);
}
@Override
public UnmutableMap asMap() {
return this;
}
@Override
public UnmutableString asString() {
return null;
}
@Override
public UnmutableList asList() {
return null;
}
@Override
public UnmutableText asText() {
return null;
}
@Override
public UnmutableFile asFile() {
return null;
}
@Override
public ReadableNumber asNumber() {
return null;
}
@Override
public ReadableBoolean asBoolean() {
return null;
}
}