// Copyright 2016 The Domain Registry 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; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Sets.difference; import static com.google.common.collect.Sets.union; import static google.registry.util.CollectionUtils.difference; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.END_OF_TIME; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedMap; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Index; import google.registry.model.eppcommon.StatusValue; import google.registry.model.eppoutput.EppResponse.ResponseData; import google.registry.model.ofy.CommitLogManifest; import google.registry.model.transfer.TransferData; import google.registry.model.transfer.TransferStatus; import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; import org.joda.time.DateTime; /** An Epp entity object such as a contact or a host. */ @XmlTransient public abstract class EppResource extends BackupGroupRoot implements Buildable, ResponseData { /** * Unique identifier in the registry for this resource. * *
This is in the (\w|_){1,80}-\w{1,8} format specified by RFC 5730 for roidType. */ @Id @XmlElement(name = "roid") String repoId; /** The ID of the registrar that is currently sponsoring this resource. */ @Index @XmlElement(name = "clID") String currentSponsorClientId; /** The ID of the registrar that created this resource. */ @XmlElement(name = "crID") String creationClientId; /** * The ID of the registrar that last updated this resource. * *
This does not refer to the last delta made on this object, which might include out-of-band
* edits; it only includes EPP-visible modifications such as {@literal This scheme allows for setting pending deletes in the future and having them magically drop
* out of the index at that time, as long as we query for resources whose deletion time is before
* now.
*/
@Index
@XmlTransient
DateTime deletionTime;
/**
* The time that this resource was last updated.
*
* This does not refer to the last delta made on this object, which might include out-of-band
* edits; it only includes EPP-visible modifications such as {@literal Can be null if the resource has never been transferred.
*/
// Map the method to XML, not the field, so subclasses can override it.
@XmlTransient
DateTime lastTransferTime;
/** Status values associated with this resource. */
Set Note: Only the last revision on a given date is stored. The key is the transaction
* timestamp, not midnight.
*
* @see google.registry.model.translators.CommitLogRevisionsTranslatorFactory
*/
@XmlTransient
ImmutableSortedMap Note: This can only be used if the creation time hasn't already been set, which it is in
* normal EPP flows.
*/
public B setCreationTime(DateTime creationTime) {
checkState(getInstance().creationTime.timestamp == null,
"creationTime can only be set once for EppResource.");
getInstance().creationTime = CreateAutoTimestamp.create(creationTime);
return thisCastToDerived();
}
/** Set the time this resource was created. Should only be used in tests. */
@VisibleForTesting
public B setCreationTimeForTest(DateTime creationTime) {
getInstance().creationTime = CreateAutoTimestamp.create(creationTime);
return thisCastToDerived();
}
/** Set the time after which this resource should be considered deleted. */
public B setDeletionTime(DateTime deletionTime) {
getInstance().deletionTime = deletionTime;
return thisCastToDerived();
}
/** Set the current sponsoring registrar. */
public B setCurrentSponsorClientId(String currentSponsorClientId) {
getInstance().currentSponsorClientId = currentSponsorClientId;
return thisCastToDerived();
}
/** Set the registrar that created this resource. */
public B setCreationClientId(String creationClientId) {
getInstance().creationClientId = creationClientId;
return thisCastToDerived();
}
/** Set the time when a {@literal This removes the {@link StatusValue#PENDING_TRANSFER} status, clears all the
* server-approve fields on the {@link TransferData} including the extended registration years
* field, and sets the expiration time of the last pending transfer (i.e. the one being cleared)
* to now.
*/
public B clearPendingTransfer(TransferStatus transferStatus, DateTime now) {
removeStatusValue(StatusValue.PENDING_TRANSFER);
return setTransferData(getInstance().getTransferData().asBuilder()
.setExtendedRegistrationYears(null)
.setServerApproveEntities(null)
.setServerApproveBillingEvent(null)
.setServerApproveAutorenewEvent(null)
.setServerApproveAutorenewPollMessage(null)
.setTransferStatus(transferStatus)
.setPendingTransferExpirationTime(now)
.build());
}
/** Wipe out any personal information in the resource. */
public B wipeOut() {
return thisCastToDerived();
}
/** Build the resource, nullifying empty strings and sets and setting defaults. */
@Override
public T build() {
// An EPP object has an implicit status of OK if no pending operations or prohibitions exist
// (i.e. no other status value besides LINKED is present).
removeStatusValue(StatusValue.OK);
if (difference(getInstance().getStatusValues(), StatusValue.LINKED).isEmpty()) {
addStatusValue(StatusValue.OK);
}
return buildWithoutImplicitStatusValues();
}
/** Build the resource, nullifying empty strings and sets and setting defaults. */
public T buildWithoutImplicitStatusValues() {
// If TransferData is totally empty, set it to null.
if (TransferData.EMPTY.equals(getInstance().transferData)) {
setTransferData(null);
}
// If there is no deletion time, set it to END_OF_TIME.
setDeletionTime(Optional.fromNullable(getInstance().deletionTime).or(END_OF_TIME));
return ImmutableObject.cloneEmptyToNull(super.build());
}
}
}
*
*
*