/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.uima.ducc.ws.registry;

@SuppressWarnings("rawtypes")
public class ServiceName implements Comparable {
	
	private String raw = null;
	
	public ServiceName(String value) {
		raw = value;
	}
	
	public String getRaw() {
		return raw;
	}
	
	public String getNormalized() {
		String normalized = raw;
		if(raw != null) {
			if(raw.contains("?")) {
				normalized = raw.substring(0, raw.indexOf("?"));
			}
		}
		return normalized;
	}
    
	@Override
	public String toString() {
		return getNormalized();
	}
	
	@Override
    public int compareTo(Object value)
    { 
        if ( value instanceof ServiceName ) {
            return getNormalized().compareTo(((ServiceName) value).getNormalized());
        } else {
            return this.compareTo(value);
        }
    }

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((getNormalized() == null) ? 0 : getNormalized().hashCode());
		return result;
	}
	
}
