package org.swellrt.beta.model.remote; import org.waveprotocol.wave.model.id.IdGenerator; import org.waveprotocol.wave.model.id.InvalidIdException; import org.waveprotocol.wave.model.id.ModernIdSerialiser; import org.waveprotocol.wave.model.id.WaveletId; import org.waveprotocol.wave.model.util.Preconditions; /** * Class representing a SNode substrate id. * <p> * A substrate has three elements: * <ul> * <li>type of the non primitive CNode</li> * <li>the document id where the CNode</li> * <li>the wavelet id where the document is stored</li> * </ul> * <p> * Example: map => m:data+34js1a:m+3jg39s * <p> * The document id must contain also the type prefix * * @author pablojan@gmail.com (Pablo Ojanguren) * */ public class SubstrateId { private static final String SEPARATOR = ":"; private static final String MAP_TYPE_PREFIX = "m"; private static final String LIST_TYPE_PREFIX = "l"; private static final String TEXT_TYPE_PREFIX = "t"; private static final String TOKEN_SEPARATOR = "+"; private final String type; private final WaveletId containerId; private final String documentId; private final String str; public static boolean isMap(SubstrateId id) { Preconditions.checkArgument(id != null, "Null substrate id"); return MAP_TYPE_PREFIX.equals(id.type); } public static boolean isText(SubstrateId id) { Preconditions.checkArgument(id != null, "Null substrate id"); return TEXT_TYPE_PREFIX.equals(id.type); } public static boolean isText(String documdentId) { Preconditions.checkArgument(documdentId != null, "Null document id"); return documdentId.startsWith(TEXT_TYPE_PREFIX+TOKEN_SEPARATOR); } private static SubstrateId of(String type, WaveletId containerId, String substrateId) { Preconditions.checkArgument(containerId != null, "Null container id"); Preconditions.checkArgument(substrateId != null, "Null substrate id"); return new SubstrateId(type, containerId, substrateId); } public static SubstrateId ofMap(WaveletId containerId, String substrateId) { Preconditions.checkArgument(substrateId.startsWith(MAP_TYPE_PREFIX+TOKEN_SEPARATOR), "Bad substrate id format"); return of(MAP_TYPE_PREFIX, containerId, substrateId); } public static SubstrateId ofList(WaveletId containerId, String substrateId) { Preconditions.checkArgument(substrateId.startsWith(LIST_TYPE_PREFIX+TOKEN_SEPARATOR), "Bad substrate id format"); return of(LIST_TYPE_PREFIX, containerId, substrateId); } public static SubstrateId ofText(WaveletId containerId, String substrateId) { Preconditions.checkArgument(substrateId.startsWith(TEXT_TYPE_PREFIX+TOKEN_SEPARATOR), "Bad substrate id format"); return of(TEXT_TYPE_PREFIX, containerId, substrateId); } public static SubstrateId deserialize(String s) { Preconditions.checkArgument(s != null && !s.isEmpty(), "String is null or empty"); String parts[] = s.split(SEPARATOR); if (parts.length != 3) return null; if (!parts[0].equals(MAP_TYPE_PREFIX) && !parts[0].equals(LIST_TYPE_PREFIX) && !parts[0].equals(TEXT_TYPE_PREFIX)) return null; if (!parts[2].startsWith(MAP_TYPE_PREFIX+TOKEN_SEPARATOR) && !parts[2].startsWith(LIST_TYPE_PREFIX+TOKEN_SEPARATOR) && !parts[2].startsWith(TEXT_TYPE_PREFIX+TOKEN_SEPARATOR)) return null; WaveletId containerId = null; try { containerId = ModernIdSerialiser.INSTANCE.deserialiseWaveletId(parts[1]); } catch (InvalidIdException e) { } if (containerId == null) return null; return SubstrateId.of(parts[0], containerId, parts[2]); } public static SubstrateId createForMap(WaveletId containerId, IdGenerator tokenGenerator) { return of(MAP_TYPE_PREFIX, containerId, MAP_TYPE_PREFIX+TOKEN_SEPARATOR+tokenGenerator.newUniqueToken()); } public static SubstrateId createForList(WaveletId containerId, IdGenerator tokenGenerator) { return of(LIST_TYPE_PREFIX, containerId, LIST_TYPE_PREFIX+TOKEN_SEPARATOR+tokenGenerator.newUniqueToken()); } public static SubstrateId createForText(WaveletId containerId, IdGenerator tokenGenerator) { return of(TEXT_TYPE_PREFIX, containerId, TEXT_TYPE_PREFIX+TOKEN_SEPARATOR+tokenGenerator.newUniqueToken()); } protected SubstrateId(String type, WaveletId containerId, String substrateId) { this.type = type; this.containerId = containerId; this.documentId = substrateId; this.str = type+SEPARATOR+ModernIdSerialiser.INSTANCE.serialiseWaveletId(containerId)+SEPARATOR+substrateId; } public boolean isList() { return LIST_TYPE_PREFIX.equals(type); } public boolean isMap() { return MAP_TYPE_PREFIX.equals(type); } public boolean isText() { return TEXT_TYPE_PREFIX.equals(type); } public String getType() { return type; } public WaveletId getContainerId() { return containerId; } public String getDocumentId() { return documentId; } public String serialize() { return str; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((containerId == null) ? 0 : containerId.hashCode()); result = prime * result + ((documentId == null) ? 0 : documentId.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; SubstrateId other = (SubstrateId) obj; if (containerId == null) { if (other.containerId != null) return false; } else if (!containerId.equals(other.containerId)) return false; if (documentId == null) { if (other.documentId != null) return false; } else if (!documentId.equals(other.documentId)) return false; if (type == null) { if (other.type != null) return false; } else if (!type.equals(other.type)) return false; return true; } }