/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * 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 org.apache.ws.scout.registry;

import org.apache.ws.scout.model.uddi.v2.DispositionReport;
import org.apache.ws.scout.model.uddi.v2.ErrInfo;
import org.apache.ws.scout.model.uddi.v2.ObjectFactory;
import org.apache.ws.scout.model.uddi.v2.Result;
 

/**
 * Thrown to indicate that a UDDI Exception was encountered.
 * 
 * <i>Borrowed from jUDDI project.</i>
 *
 * @author Steve Viens (sviens@apache.org)
 */
public class RegistryException extends Exception
{
	private static final long serialVersionUID = -6628826473199096011L;
	public static final int E_ASSERTION_NOT_FOUND = 30000;
	public static final int E_AUTH_TOKEN_EXPIRED = 10110;
	public static final int E_AUTH_TOKEN_REQUIRED = 10120;
	public static final int E_ACCOUNT_LIMIT_EXCEEDED = 10160;
	public static final int E_BUSY = 10400;
	public static final int E_CATEGORIZATION_NOT_ALLOWED = 20100;
	public static final int E_FATAL_ERROR = 10500;
	public static final int E_INVALID_KEY_PASSED = 10210;
	public static final int E_INVALID_PROJECTION = 20230;
	public static final int E_INVALID_CATEGORY = 20000;
	public static final int E_INVALID_COMPLETION_STATUS = 30100;
	public static final int E_INVALID_URL_PASSED = 10220;
	public static final int E_INVALID_VALUE = 20200;
	public static final int E_KEY_RETIRED = 10310;
	public static final int E_LANGUAGE_ERROR = 10060;
	public static final int E_MESSAGE_TOO_LARGE = 30110;
	public static final int E_NAME_TOO_LONG = 10020;
	public static final int E_OPERATOR_MISMATCH = 10130;
	public static final int E_PUBLISHER_CANCELLED = 30220;
	public static final int E_REQUEST_DENIED = 30210;
	public static final int E_SECRET_UNKNOWN = 30230;
	public static final int E_SUCCESS = 0;
	public static final int E_TOO_MANY_OPTIONS = 10030;
	public static final int E_TRANSFER_ABORTED = 30200;
	public static final int E_UNRECOGNIZED_VERSION = 10040;
	public static final int E_UNKNOWN_USER = 10150;
	public static final int E_UNSUPPORTED = 10050;
	public static final int E_USER_MISMATCH = 10140;
	public static final int E_VALUE_NOT_ALLOWED = 20210;
	public static final int E_UNVALIDATABLE = 20220;
	public static final int E_REQUEST_TIMEOUT = 20240;
	public static final int E_INVALID_TIME = 40030;
	public static final int E_RESULT_SET_TOO_LARGE = 40300;

  // SOAP SOAPFault Actor
  private String faultActor;

  // SOAP SOAPFault Code
  private String faultCode;

  // SOAP SOAPFault SOAPMessage
  private String faultString;

  // UDDI DispositionReport
  private DispositionReport dispReport;
  
  private ObjectFactory objectFactory = new ObjectFactory();

  /**
   * Constructs a RegistryException instance.
   * @param msg additional error information
   */
  public RegistryException(String msg)
  {
    super(msg);

    setFaultCode(null);
    setFaultString(msg);
    setFaultActor(null);
  }

  /**
   * Constructs a RegistryException instance.
   * @param ex the original exception
   */
  public RegistryException(Exception ex)
  {
    super(ex);
    
    if (ex != null)
    {
      // Not sure why this would ever happen but 
      // just in case we are asked to create a new
      // RegistryException using values from another
      // let's be sure to grab all relevant values.
      //
      if (ex instanceof RegistryException)
      {
        RegistryException regex = (RegistryException)ex;
        setFaultCode(regex.getFaultCode());
        setFaultString(regex.getFaultString());
        setFaultActor(regex.getFaultActor());
        setDispositionReport(regex.getDispositionReport());
      }
      else // Not a RegistryException (or subclass)
      {
        setFaultString(ex.getMessage());
      }
    }
  }

  /**
   * Constructs a RegistryException instance.
   * 
   * @param fCode
   * @param fString
   * @param fActor
   * @param dispRpt
   */
  public RegistryException(String fCode,String fString,String fActor,DispositionReport dispRpt)
  {
    super(fString);

    setFaultCode(fCode);
    setFaultString(fString);
    setFaultActor(fActor);
    setDispositionReport(dispRpt);
  }

  /**
   * Constructs a RegistryException instance.
   * @param ex the original exception
   */
  RegistryException(String fCode,int errno,String msg)
  {
    super(buildMessage(errno,msg));

    String errCode = lookupErrCode(errno);

    if (fCode != null) {
    	setFaultCode(fCode);
    }
    
    setFaultString(getMessage());
    
    Result r = this.objectFactory.createResult();
    ErrInfo ei = this.objectFactory.createErrInfo();

    if (errCode != null) {
    	ei.setErrCode(errCode);
    }

    ei.setValue(getMessage());

   	r.setErrno(errno);

    if (ei != null) {
    	r.setErrInfo(ei);
    }

    addResult(r);
  }

  /**
   * Sets the fault actor of this SOAP SOAPFault to the given value.
   * @param actor The new actor value for this SOAP SOAPFault.
   */
  public void setFaultActor(String actor)
  {
    this.faultActor = actor;
  }

  /**
   * Returns the fault actor of this SOAP SOAPFault.
   * @return The fault actor of this SOAP SOAPFault.
   */
  public String getFaultActor()
  {
    return this.faultActor;
  }

  /**
   * Sets the fault code of this SOAP SOAPFault to the given value.
   * @param code The new code number for this SOAP SOAPFault.
   */
  public void setFaultCode(String code)
  {
    this.faultCode = code;
  }

  /**
   * Returns the fault code of this SOAP SOAPFault.
   * @return The fault code of this SOAP SOAPFault.
   */
  public String getFaultCode()
  {
    return this.faultCode;
  }

  /**
   * Sets the fault string of this SOAP SOAPFault to the given value.
   * @param value The new fault string for this SOAP SOAPFault.
   */
  public void setFaultString(String value)
  {
    this.faultString = value;
  }

  /**
   * Returns the fault string of this SOAP SOAPFault.
   * @return The fault string of this SOAP SOAPFault.
   */
  public String getFaultString()
  {
    return this.faultString;
  }

  /**
   * Sets the UDDI DispositionReport value to the instance
   * specified
   * @param dispRpt The new UDDI DispositionReport instance for
   *  this SOAP Fault.
   */
  public void setDispositionReport(DispositionReport dispRpt)
  {
    this.dispReport = dispRpt;
  }

  /**
   * Returns the disposition report associated with this jUDDI exception. It
   * uses the results Vector to determine if a disposition report is present
   * and should be returned.
   * @return The disposition report associated with this jUDDI exception.
   */
  public DispositionReport getDispositionReport()
  {
    return this.dispReport;
  }

  /**
   * Adds a result instance to this Exception. Multiple result objects
   * may exist within a DispositionReport
   */
  public void addResult(Result result)
  {
    if (this.dispReport==null) {
      this.dispReport = this.objectFactory.createDispositionReport();
    }

    Result jaxbResult = this.objectFactory.createResult();
    this.dispReport.getResult().add(jaxbResult);
    
    if (result.getErrInfo() != null) jaxbResult.setErrInfo(result.getErrInfo());
    if (result.getKeyType() != null) jaxbResult.setKeyType(result.getKeyType());
    jaxbResult.setErrno(result.getErrno());
  }

  /**
   *
   */
  public String toString()
  {
    String msg = getMessage();
    if (msg == null)
      return "";
    else
      return getMessage();
  }
  
  private static final String buildMessage(int errno,String msg)
  {
    StringBuffer buffer = new StringBuffer();
    
    String errCode = lookupErrCode(errno);
    if (errCode != null)
    {
      buffer.append(errCode);
      buffer.append(" ");
    }
    
    buffer.append("(");
    buffer.append(errno);
    buffer.append(") ");
    
    //String errText = lookupErrText(errno);
    // FIXME: What should error text be?
    String errText = "";
    if (errText != null)
    {
      buffer.append(errText);
      buffer.append(" ");
    }
    
    if ((msg != null) && (msg.trim().length() > 0))
    {
      buffer.append(msg);
    }
    
    return buffer.toString();
  }

  public static final String lookupErrCode(int errno)
  {
	  switch (errno)
	  {
	  case E_ACCOUNT_LIMIT_EXCEEDED     : return "E_accountLimitExceeded";
	  case E_ASSERTION_NOT_FOUND        : return "E_assertionNotFound"; 
	  case E_AUTH_TOKEN_EXPIRED         : return "E_authTokenExpired";
	  case E_AUTH_TOKEN_REQUIRED        : return "E_authTokenRequired";
	  case E_BUSY                       : return "E_busy";
	  case E_CATEGORIZATION_NOT_ALLOWED : return "E_categorizationNotAllowed";
	  case E_FATAL_ERROR                : return "E_fatalError";
	  case E_INVALID_CATEGORY           : return "E_invalidCategory";
	  case E_INVALID_COMPLETION_STATUS  : return "E_invalidCompletionStatus";
	  case E_INVALID_KEY_PASSED         : return "E_invalidKeyPassed";
	  case E_INVALID_PROJECTION         : return "E_invalidProjection";
	  case E_INVALID_TIME               : return "E_invalidTime";
	  case E_INVALID_URL_PASSED         : return "E_invalidURLPassed";
	  case E_INVALID_VALUE              : return "E_invalidValue";
	  case E_KEY_RETIRED                : return "E_keyRetired";
	  case E_LANGUAGE_ERROR             : return "E_languageError";
	  case E_MESSAGE_TOO_LARGE          : return "E_messageTooLarge";
	  case E_NAME_TOO_LONG              : return "E_nameTooLong";
	  case E_OPERATOR_MISMATCH          : return "E_operatorMismatch";
	  case E_PUBLISHER_CANCELLED        : return "E_publisherCancelled";
	  case E_REQUEST_DENIED             : return "E_requestDenied";
	  case E_REQUEST_TIMEOUT            : return "E_requestTimeout";
	  case E_RESULT_SET_TOO_LARGE       : return "E_resultSetTooLarge";
	  case E_SECRET_UNKNOWN             : return "E_secretUnknown";
	  case E_SUCCESS                    : return "E_success";
	  case E_TOO_MANY_OPTIONS           : return "E_tooManyOptions";
	  case E_TRANSFER_ABORTED           : return "E_transferAborted";
	  case E_UNKNOWN_USER               : return "E_unknownUser";
	  case E_UNRECOGNIZED_VERSION       : return "E_unrecognizedVersion";
	  case E_UNSUPPORTED                : return "E_unsupported";
	  case E_UNVALIDATABLE              : return "E_unvalidatable";
	  case E_USER_MISMATCH              : return "E_userMismatch";
	  case E_VALUE_NOT_ALLOWED          : return "E_valueNotAllowed";
	  default                           : return null;
	  }
  }  
}