/****************************************************************************
* Copyright (c) 2005, 2010 Jan S. Rellermeyer, Systems Group,
* Department of Computer Science, ETH Zurich and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Jan S. Rellermeyer - initial API and implementation
* Markus Alexander Kuppe - enhancements and bug fixes
*
*****************************************************************************/
package ch.ethz.iks.slp;
import java.io.Serializable;
/**
* Implementation of the SLP ServiceType class defined in RFC 2614.
*
* @author Jan S. Rellermeyer, Systems Group, ETH Zurich
* @since 1.0
*/
public final class ServiceType implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2821061127250972623L;
/**
* the type.
*/
private String type = new String();
/**
* is it abstract ?
*/
private final boolean isAbstract;
/**
* the concrete type.
*/
private final String concreteType;
/**
* the principle type.
*/
private final String principleType;
/**
* the abstract type.
*/
private final String abstractType;
/**
* the naming authority.
*/
private final String namingAuthority;
/**
* creates a new ServiceType instance.
*
* @param serviceType
* the string representation of a ServiceType, e.g.
*
* <pre>
* service:osgi:remote
* </pre>
*/
public ServiceType(final String serviceType) {
type = serviceType;
if (!type.startsWith("service:")) {
throw new IllegalArgumentException("Invalid service type: "
+ serviceType);
}
final int principleStart = 8;
final int principleEnd = type.indexOf(":", principleStart);
if (principleEnd != -1) {
isAbstract = true;
principleType = type.substring(principleStart, principleEnd);
abstractType = type.substring(0, principleEnd);
concreteType = type.substring(principleEnd + 1);
} else {
isAbstract = false;
principleType = type.substring(principleStart);
abstractType = "";
concreteType = "";
}
final int namingStart = type.indexOf(".") + 1;
if (namingStart != 0) {
final int namingEnd = type.indexOf(":", namingStart);
String na = "";
if (namingEnd == -1) {
na = type.substring(namingStart);
} else {
na = type.substring(namingStart, namingEnd);
}
// 1954772: isNADefault returns false for "IANA"
if ("IANA".equalsIgnoreCase(na)) {
namingAuthority = "";
// remove "iana" from type so toString() is consistent
type = type.substring(0, namingStart - 1)
+ type.substring(namingStart + 4, type.length());
} else {
namingAuthority = na;
}
} else {
namingAuthority = "";
}
}
/**
* Always returns true as invalid service types cannot be created any longer.
*
* @return always true.
*/
public boolean isServiceURL() {
//Kept for API compatibility
//Remove when moved to next major
return true;
}
/**
* is the ServiceType instance an abstract type ?
*
* @return true if thie is the case.
*/
public boolean isAbstractType() {
return isAbstract;
}
/**
* is the naming authority default (IANA) ?
*
* @return true if this is the case.
*/
public boolean isNADefault() {
return "".equals(namingAuthority);
}
/**
* get the concrete type part of this ServiceType instance.
*
* @return a String representing the concrete type.
*/
public String getConcreteTypeName() {
return concreteType;
}
/**
* get the principle type part of this ServiceType instance.
*
* @return a String representing the principle part.
*/
public String getPrincipleTypeName() {
return principleType;
}
/**
* get the name of the abstract type of this ServiceType instance.
*
* @return a String representing the abstract type.
*/
public String getAbstractTypeName() {
return abstractType;
}
/**
* get the naming authority.
*
* @return the naming authority.
*/
public String getNamingAuthority() {
return namingAuthority;
}
/**
* check if two ServiceTypes are equal.
*
* @param obj
* another ServiceType.
* @return true if they equal.
*/
public boolean equals(final Object obj) {
if (!(obj instanceof ServiceType)) {
return false;
}
final ServiceType t = (ServiceType) obj;
return (isAbstract == t.isAbstract
&& concreteType.equals(t.concreteType)
&& principleType.equals(t.principleType)
&& abstractType.equals(t.abstractType) && namingAuthority
.equals(t.namingAuthority));
}
/**
* check if a ServiceType matches a ServiceURL or another ServiceType.
*
* @param obj
* the object to be compared to.
* @return true if this type matches the other object.
*/
public boolean matches(final Object obj) {
if (!(obj instanceof ServiceType)) {
return false;
}
final ServiceType t = (ServiceType) obj;
return isAbstract ? equals(t)
|| t.toString().equals(getAbstractTypeName()) : equals(t);
}
/**
* get a String representation of this ServiceType instance.
*
* @return the String representation.
*/
public String toString() {
return type;
}
/**
* get the hashCode of this ServiceType instance.
*
* @return the int value of the hashCode.
*/
public int hashCode() {
return (concreteType.hashCode()) ^ (principleType.hashCode() << 24)
^ (abstractType.hashCode() << 16)
^ (namingAuthority.hashCode() << 8);
}
}