// 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.eppoutput; import static google.registry.util.XmlEnumUtils.enumToXml; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import google.registry.model.ImmutableObject; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlEnumValue; /** * "If the command was processed successfully, only one {@code Result} element MUST be returned. If * the command was not processed successfully, multiple {@code Result} elements MAY be returned to * document failure conditions." */ public class Result extends ImmutableObject { /** * "EPP result codes are based on the theory of reply codes described in section 4.2.1 of * [RFC5321]. EPP uses four decimal digits to describe the success or failure of each EPP command. * Each of the digits of the reply have special significance." * * "The first digit denotes command success or failure. The second digit denotes the response * category, such as command syntax or security. The third and fourth digits provide explicit * response detail within each response category." */ public enum Code { @XmlEnumValue("1000") Success("Command completed successfully"), @XmlEnumValue("1001") SuccessWithActionPending("Command completed successfully; action pending"), @XmlEnumValue("1300") SuccessWithNoMessages("Command completed successfully; no messages"), @XmlEnumValue("1301") SuccessWithAckMessage("Command completed successfully; ack to dequeue"), @XmlEnumValue("1500") SuccessAndClose("Command completed successfully; ending session"), @XmlEnumValue("2000") UnknownCommand("Unknown command"), @XmlEnumValue("2001") SyntaxError("Command syntax error"), @XmlEnumValue("2002") CommandUseError("Command use error"), @XmlEnumValue("2003") RequiredParameterMissing("Required parameter missing"), @XmlEnumValue("2004") ParameterValueRangeError("Parameter value range error"), @XmlEnumValue("2005") ParameterValueSyntaxError("Parameter value syntax error"), @XmlEnumValue("2100") UnimplementedProtocolVersion("Unimplemented protocol version"), @XmlEnumValue("2101") UnimplementedCommand("Unimplemented command"), @XmlEnumValue("2102") UnimplementedOption("Unimplemented option"), @XmlEnumValue("2103") UnimplementedExtension("Unimplemented extension"), @XmlEnumValue("2200") AuthenticationError("Authentication error"), @XmlEnumValue("2201") AuthorizationError("Authorization error"), @XmlEnumValue("2202") InvalidAuthorizationInformationError("Invalid authorization information"), @XmlEnumValue("2300") ObjectPendingTransfer("Object pending transfer"), @XmlEnumValue("2301") ObjectNotPendingTransfer("Object not pending transfer"), @XmlEnumValue("2302") ObjectExists("Object exists"), @XmlEnumValue("2303") ObjectDoesNotExist("Object does not exist"), @XmlEnumValue("2304") StatusProhibitsOperation("Object status prohibits operation"), @XmlEnumValue("2305") AssociationProhibitsOperation("Object association prohibits operation"), @XmlEnumValue("2306") ParameterValuePolicyError("Parameter value policy error"), @XmlEnumValue("2307") UnimplementedObjectService("Unimplemented object service"), @XmlEnumValue("2400") CommandFailed("Command failed"), @XmlEnumValue("2501") AuthenticationErrorClosingConnection("Authentication error; server closing connection"); /** A four-digit (positive) number that describes the success or failure of the command. */ public final int code; /** A human-readable description of the response code. */ public final String msg; /** * An RFC 4646 language code. * * @see "http://tools.ietf.org/html/rfc4646" */ public final String msgLang; /** @param msg a human-readable description of the response code; required. */ Code(String msg) { this.code = Integer.parseInt(enumToXml(this)); Preconditions.checkArgument( (int) Math.log10(code) == 3, "Response code must be a four-digit (positive) number."); this.msg = Preconditions.checkNotNull(msg, "A message must be specified."); this.msgLang = "en"; // All of our messages are English. } /** @return true iff the response code is in the 1xxx category, representing success. */ public boolean isSuccess() { return code < 2000; } @Override public String toString() { return String.format("{code:'%s', msg:'%s', msgLang:'%s'}", code, msg, msgLang); } } /** The result code for this result. This is always present. */ @XmlAttribute Code code; /** An explanation of the result code. */ String msg; public Code getCode() { return code; } public String getMsg() { return msg; } public static Result create(Code code, String msg) { Result instance = new Result(); instance.code = code; // If no message was set, pick up a default message from the Code enum. Preconditions.checkState( !code.isSuccess() || msg == null, "Only error result codes may have a message"); instance.msg = MoreObjects.firstNonNull(msg, code.msg); return instance; } public static Result create(Code code) { return create(code, null); } }