package org.atlasapi.persistence.lookup.mongo; import static com.metabroadcast.common.persistence.mongo.MongoConstants.ID; import java.util.Set; import org.atlasapi.media.entity.Alias; import org.atlasapi.media.entity.LookupRef; import org.atlasapi.persistence.lookup.entry.LookupEntry; import org.atlasapi.persistence.media.entity.AliasTranslator; import org.atlasapi.persistence.media.entity.LookupRefTranslator; import org.joda.time.DateTime; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.metabroadcast.common.persistence.translator.TranslatorUtils; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; public class LookupEntryTranslator { private static final String EXPLICIT = "explicit"; private static final String DIRECT = "direct"; private static final String EQUIVS = "equivs"; private static final String LAST_UPDATED = "updated"; private static final String FIRST_CREATED = "created"; public static final String ACTIVELY_PUBLISHED = "activelyPublished"; public static final String ALIASES = "aliases"; public static final String IDS = "ids"; public static final String OPAQUE_ID = "aid"; public static final String SELF = "self"; private final AliasTranslator aliasTranslator = new AliasTranslator(); private static final LookupRefTranslator lookupRefTranslator = new LookupRefTranslator(); public Function<LookupEntry, DBObject> TO_DBO = new Function<LookupEntry, DBObject>() { @Override public DBObject apply(LookupEntry input) { return toDbo(input); } }; public Function<DBObject, LookupEntry> FROM_DBO = new Function<DBObject, LookupEntry>() { @Override public LookupEntry apply(DBObject dbo) { return fromDbo(dbo); } }; public DBObject toDbo(LookupEntry entry) { BasicDBObject dbo = new BasicDBObject(); TranslatorUtils.from(dbo, ID, entry.uri()); TranslatorUtils.from(dbo, OPAQUE_ID, entry.id()); TranslatorUtils.from(dbo, SELF, refToDbo.apply(entry.lookupRef())); Set<String> aliases = Sets.newHashSet(entry.uri()); aliases.addAll(entry.aliasUrls()); TranslatorUtils.fromSet(dbo, aliases, ALIASES); TranslatorUtils.from(dbo, IDS, aliasTranslator.toDBList(entry.aliases())); translateRefsInToField(dbo, EQUIVS, entry.equivalents()); translateRefsInToField(dbo, DIRECT, entry.directEquivalents()); translateRefsInToField(dbo, EXPLICIT, entry.explicitEquivalents()); TranslatorUtils.fromDateTime(dbo, FIRST_CREATED, entry.created()); TranslatorUtils.fromDateTime(dbo, LAST_UPDATED, entry.updated()); if (!entry.activelyPublished()) { TranslatorUtils.from(dbo, ACTIVELY_PUBLISHED, entry.activelyPublished()); } return dbo; } private void translateRefsInToField(BasicDBObject dbo, String field, Set<LookupRef> refs) { BasicDBList refDbos = new BasicDBList(); refDbos.addAll(ImmutableSet.copyOf(Iterables.transform(refs, refToDbo))); TranslatorUtils.from(dbo, field, refDbos); } private static Function<LookupRef, DBObject> refToDbo = new Function<LookupRef, DBObject>() { @Override public DBObject apply(LookupRef input) { return lookupRefTranslator.toDBObject(null, input); } }; public LookupEntry fromDbo(DBObject dbo) { if(dbo == null) { return null; } String uri = TranslatorUtils.toString(dbo, ID); Long id = TranslatorUtils.toLong(dbo, OPAQUE_ID); Set<String> aliasUris = TranslatorUtils.toSet(dbo, ALIASES); aliasUris.add(uri); Set<Alias> aliases = aliasTranslator.fromDBObjects(TranslatorUtils.toDBObjectList(dbo, IDS)); LookupRef self = lookupRefTranslator.fromDBObject(TranslatorUtils.toDBObject(dbo, SELF), null); Set<LookupRef> equivs = translateRefs(self, dbo, EQUIVS); Set<LookupRef> directEquivalents = translateRefs(self, dbo, DIRECT); Set<LookupRef> explicitEquivalents = translateRefs(self, dbo, EXPLICIT); DateTime created = TranslatorUtils.toDateTime(dbo, FIRST_CREATED); DateTime updated = TranslatorUtils.toDateTime(dbo, LAST_UPDATED); boolean activelyPublished = true; if (dbo.containsField(ACTIVELY_PUBLISHED)) { activelyPublished = TranslatorUtils.toBoolean(dbo, ACTIVELY_PUBLISHED); } return new LookupEntry(uri, id, self, aliasUris, aliases, directEquivalents, explicitEquivalents, equivs, created, updated, activelyPublished); } public DBObject removeFieldsForHash(DBObject dbo) { if (dbo == null) { return null; } dbo.removeField(LAST_UPDATED); dbo.removeField(FIRST_CREATED); return dbo; } private ImmutableSet<LookupRef> translateRefs(LookupRef seflRef, DBObject dbo, String field) { return ImmutableSet.<LookupRef>builder() .add(seflRef) .addAll(Iterables.transform(TranslatorUtils.toDBObjectList(dbo, field), refFromDbo)) .build(); } private static final Function<DBObject, LookupRef> refFromDbo = new Function<DBObject, LookupRef>() { @Override public LookupRef apply(DBObject input) { return lookupRefTranslator.fromDBObject(input, null); } }; }