mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 12:07:51 +02:00
The dark lord Gosling designed the Java package naming system so that ownership flows from the DNS system. Since we own the domain name registry.google, it seems only appropriate that we should use google.registry as our package name.
153 lines
5.2 KiB
Java
153 lines
5.2 KiB
Java
// 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.eppinput;
|
|
|
|
import static com.google.common.collect.Sets.intersection;
|
|
import static google.registry.util.CollectionUtils.nullSafeImmutableCopy;
|
|
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.ImmutableSet;
|
|
|
|
import google.registry.model.Buildable.Builder;
|
|
import google.registry.model.EppResource;
|
|
import google.registry.model.ImmutableObject;
|
|
import google.registry.model.eppcommon.AuthInfo;
|
|
import google.registry.model.eppcommon.StatusValue;
|
|
import google.registry.util.TypeUtils.TypeInstantiator;
|
|
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
import javax.xml.bind.annotation.XmlElement;
|
|
import javax.xml.bind.annotation.XmlElements;
|
|
import javax.xml.bind.annotation.XmlTransient;
|
|
|
|
/** Commands for EPP resources. */
|
|
public interface ResourceCommand {
|
|
|
|
/**
|
|
* A command for a single {@link EppResource}.
|
|
* <p>
|
|
* In general commands should extend {@link AbstractSingleResourceCommand} instead of
|
|
* implementing this directly, but "Create" commands can't do that since they need to inherit
|
|
* from a base class that gives them all of the resource's fields. The domain "Info" command
|
|
* also can't do that since it's "name" field is overloaded with a "hosts" attribute.
|
|
*/
|
|
public interface SingleResourceCommand extends ResourceCommand {
|
|
String getTargetId();
|
|
|
|
AuthInfo getAuthInfo();
|
|
}
|
|
|
|
/** Abstract implementation of {@link ResourceCommand}. */
|
|
@XmlTransient
|
|
public abstract static class AbstractSingleResourceCommand extends ImmutableObject
|
|
implements SingleResourceCommand {
|
|
@XmlElements({
|
|
@XmlElement(name = "id"),
|
|
@XmlElement(name = "name") })
|
|
String targetId;
|
|
|
|
@Override
|
|
public String getTargetId() {
|
|
return targetId;
|
|
}
|
|
|
|
@Override
|
|
public AuthInfo getAuthInfo() {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/** A check command for an {@link EppResource}. */
|
|
@XmlTransient
|
|
public static class ResourceCheck extends ImmutableObject implements ResourceCommand {
|
|
@XmlElements({
|
|
@XmlElement(name = "id"),
|
|
@XmlElement(name = "name") })
|
|
List<String> targetUniqueIds;
|
|
|
|
public ImmutableList<String> getTargetIds() {
|
|
return nullSafeImmutableCopy(targetUniqueIds);
|
|
}
|
|
}
|
|
|
|
/** A create command, or the inner change (as opposed to add or remove) part of an update. */
|
|
public interface ResourceCreateOrChange<B extends Builder<?>> {
|
|
public abstract void applyTo(B builder);
|
|
}
|
|
|
|
/**
|
|
* An update command for an {@link EppResource}.
|
|
*
|
|
* @param <A> the add-remove type
|
|
* @param <C> the change type
|
|
*/
|
|
@XmlTransient
|
|
public abstract static class ResourceUpdate
|
|
<A extends ResourceUpdate.AddRemove,
|
|
B extends EppResource.Builder<?, ?>,
|
|
C extends ResourceCreateOrChange<B>> extends AbstractSingleResourceCommand {
|
|
|
|
/** Part of an update command that specifies set values to add or remove. */
|
|
@XmlTransient
|
|
public abstract static class AddRemove extends ImmutableObject {
|
|
@XmlElement(name = "status")
|
|
Set<StatusValue> statusValues;
|
|
|
|
public ImmutableSet<StatusValue> getStatusValues() {
|
|
return nullToEmptyImmutableCopy(statusValues);
|
|
}
|
|
}
|
|
|
|
protected abstract C getNullableInnerChange();
|
|
|
|
protected abstract A getNullableInnerAdd();
|
|
|
|
protected abstract A getNullableInnerRemove();
|
|
|
|
// Don't use MoreObjects.firstNonNull in these method because it will result in an unneeded
|
|
// reflective instantiation when the object isn't null.
|
|
|
|
public C getInnerChange() {
|
|
C change = getNullableInnerChange();
|
|
return change == null ? new TypeInstantiator<C>(getClass()){}.instantiate() : change;
|
|
}
|
|
|
|
public A getInnerAdd() {
|
|
A add = getNullableInnerAdd();
|
|
return add == null ? new TypeInstantiator<A>(getClass()){}.instantiate() : add;
|
|
}
|
|
|
|
public A getInnerRemove() {
|
|
A remove = getNullableInnerRemove();
|
|
return remove == null ? new TypeInstantiator<A>(getClass()){}.instantiate() : remove;
|
|
}
|
|
|
|
public void applyTo(B builder) throws AddRemoveSameValueException {
|
|
getInnerChange().applyTo(builder);
|
|
if (!intersection(getInnerAdd().getStatusValues(), getInnerRemove().getStatusValues())
|
|
.isEmpty()) {
|
|
throw new AddRemoveSameValueException();
|
|
}
|
|
builder.addStatusValues(getInnerAdd().getStatusValues());
|
|
builder.removeStatusValues(getInnerRemove().getStatusValues());
|
|
}
|
|
}
|
|
|
|
/** Exception for adding and removing the same value in {@link ResourceUpdate#applyTo}. */
|
|
public static class AddRemoveSameValueException extends Exception {}
|
|
}
|