<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>ErrorMessage.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">jUDDI Core Services</a> &gt; <a href="index.source.html" class="el_package">org.apache.juddi.v3.error</a> &gt; <span class="el_source">ErrorMessage.java</span></div><h1>ErrorMessage.java</h1><pre class="source lang-java linenums">/*
 * Copyright 2001-2008 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
 * 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 &quot;AS IS&quot; 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.juddi.v3.error;

import org.apache.juddi.config.ResourceConfig;

/**
 * @author &lt;a href=&quot;mailto:jfaath@apache.org&quot;&gt;Jeff Faath&lt;/a&gt;
 */
public class ErrorMessage {
	private String message;
	private String value;
	
	public ErrorMessage(String messageCode) {
<span class="fc" id="L30">		this(messageCode, null);</span>
<span class="fc" id="L31">	}</span>
	
<span class="fc" id="L33">	public ErrorMessage(String messageCode, String value) {</span>
<span class="fc" id="L34">		this.message = ResourceConfig.getGlobalMessage(messageCode);</span>
<span class="fc" id="L35">		this.value = value;</span>
<span class="fc" id="L36">	}</span>

	public String getMessage() {
<span class="nc" id="L39">		return message;</span>
	}

	public void setMessage(String message) {
<span class="nc" id="L43">		this.message = message;</span>
<span class="nc" id="L44">	}</span>

	public String getValue() {
<span class="nc" id="L47">		return value;</span>
	}

	public void setValue(String value) {
<span class="nc" id="L51">		this.value = value;</span>
<span class="nc" id="L52">	}</span>
	
	public String toString() {
<span class="pc bpc" id="L55" title="1 of 4 branches missed.">		if (value == null || value.length() == 0)</span>
<span class="fc" id="L56">			return message;</span>
		else
<span class="fc" id="L58">			return message + &quot;:  &quot; + value;</span>
			
	}
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.7.9.201702052155</span></div></body></html>