// Copyright 2016 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package google.registry.model.poll; import static google.registry.model.ofy.ObjectifyService.ofy; import com.google.common.base.Converter; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableBiMap; import com.googlecode.objectify.Key; import google.registry.model.EppResource; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; import google.registry.model.host.HostResource; import google.registry.model.reporting.HistoryEntry; import java.util.List; /** * A converter between external key strings for {@link PollMessage}s (i.e. what registrars use to * identify and ACK them) and Datastore keys to the resource. * *

The format of the key string is A-B-C-D-E as follows: * *

 *   A = EppResource.typeId (decimal)
 *   B = EppResource.repoId prefix (STRING)
 *   C = EppResource.repoId suffix (STRING)
 *   D = HistoryEntry.id (decimal)
 *   E = PollMessage.id (decimal)
 * 
*/ public class PollMessageExternalKeyConverter extends Converter, String> { /** An exception thrown when an external key cannot be parsed. */ public static class PollMessageExternalKeyParseException extends RuntimeException {} /** * A map of IDs used in external keys corresponding to which EppResource class the poll message * belongs to. */ public static final ImmutableBiMap, Long> EXTERNAL_KEY_CLASS_ID_MAP = ImmutableBiMap., Long>of( DomainBase.class, 1L, ContactResource.class, 2L, HostResource.class, 3L); @Override protected String doForward(Key key) { @SuppressWarnings("unchecked") Key ancestorResource = (Key) (Key) key.getParent().getParent(); long externalKeyClassId = EXTERNAL_KEY_CLASS_ID_MAP.get( ofy().factory().getMetadata(ancestorResource.getKind()).getEntityClass()); return String.format("%d-%s-%d-%d", externalKeyClassId, ancestorResource.getName(), key.getParent().getId(), key.getId()); } /** * Returns an Objectify Key to a PollMessage corresponding with the external key string. * * @throws PollMessageExternalKeyParseException if the external key has an invalid format. */ @Override protected Key doBackward(String externalKey) { List idComponents = Splitter.on('-').splitToList(externalKey); if (idComponents.size() != 5) { throw new PollMessageExternalKeyParseException(); } try { Class resourceClazz = EXTERNAL_KEY_CLASS_ID_MAP.inverse().get(Long.parseLong(idComponents.get(0))); if (resourceClazz == null) { throw new PollMessageExternalKeyParseException(); } return Key.create( Key.create( Key.create( null, resourceClazz, String.format("%s-%s", idComponents.get(1), idComponents.get(2))), HistoryEntry.class, Long.parseLong(idComponents.get(3))), PollMessage.class, Long.parseLong(idComponents.get(4))); } catch (NumberFormatException e) { throw new PollMessageExternalKeyParseException(); } } }