/******************************************************************************* * Copyright (c) 2004 Composent, Inc. 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: Composent, Inc. - initial API and implementation ******************************************************************************/ package org.eclipse.ecf.core.identity; import java.io.Serializable; import org.eclipse.core.runtime.*; import org.eclipse.ecf.internal.core.identity.Activator; /** * Namespace base class. *
* This class and subclasses define a namespace for the creation and management * of ID instances. Creation of ID instances is accomplished via the * {@link #createInstance(Object[])} method, implemented by subclasses of this * Namespace superclass. *
* All Namespace instances must have a unique name passed to the Namespace upon * construction. *
* Typically Namespace instances are created via plugins that define extensions * of the org.eclipse.ecf.namespace extension point. For example, to define a * new Namespace subclass XMPPNamespace with name "ecf.xmpp" and add it to the * ECF extension registry: * *
* <extension * point="org.eclipse.ecf.namespace"> * <namespace * class="XMPPNamespace" * name="ecf.xmpp"/> * </extension> ** * @see ID */ public abstract class Namespace implements Serializable, IAdaptable { private static final long serialVersionUID = 3976740272094720312L; public static final String SCHEME_SEPARATOR = ":"; //$NON-NLS-1$ private String name; private String description; private int hashCode; private boolean isInitialized = false; public Namespace() { // public null constructor } public final boolean initialize(String n, String desc) { Assert.isNotNull(n, "Namespace
null
.
* @param second
* the second ID. Must not be null
.
* @return true
if this ID is equal to the given ID.
* false
otherwise.
*/
protected boolean testIDEquals(BaseID first, BaseID second) {
// First check that namespaces are the same and non-null
Namespace sn = second.getNamespace();
if (sn == null || !this.equals(sn))
return false;
return first.namespaceEquals(second);
}
/**
* The default implementation of this method is to call
* id.namespaceGetName(). Subclasses may override.
*
* @param id
* the ID to get the name for. Must not be null
.
* @return String that is the unique name for the given id within this
* Namespace.
*/
protected String getNameForID(BaseID id) {
return id.namespaceGetName();
}
/**
* The default implementation of this method is to call
* first.namespaceCompareTo(second). Subclasses may override.
*
* @param first
* the first id to compare. Must not be null
.
* @param second
* the second id to compare. Must not be null
.
* @return int as specified by {@link Comparable}.
*/
protected int getCompareToForObject(BaseID first, BaseID second) {
return first.namespaceCompareTo(second);
}
/**
* The default implementation of this method is to call
* id.namespaceHashCode(). Subclasses may override.
*
* @param id
* the id in this Namespace to get the hashcode for. Must not be
* null
.
* @return the hashcode for the given id. Returned value must be unique
* within this process.
*/
protected int getHashCodeForID(BaseID id) {
return id.namespaceHashCode();
}
/**
* The default implementation of this method is to call
* id.namespaceToExternalForm(). Subclasses may override.
*
* @param id
* the id in this Namespace to convert to external form.
* @return String that represents the given id in an external form. Note
* that this external form may at some later time be passed to
* {@link #createInstance(Object[])} as a single String parameter,
* and should result in a valid ID instance of the appropriate
* Namespace.
*/
protected String toExternalForm(BaseID id) {
return id.namespaceToExternalForm();
}
/**
* Get the name of this namespace. Must not return null
.
*
* @return String name of Namespace instance. Must not return
* null
, and the returned value should be a globally
* unique name for this Namespace subclass.
*
*/
public String getName() {
return name;
}
/**
* Get the description, associated with this Namespace. The returned value
* may be null
.
*
* @return the description associated with this Namespace. May be
* null
.
*/
public String getDescription() {
return description;
}
/**
* Make an instance of this namespace. Namespace subclasses, provided by
* plugins must implement this method to construct ID instances for the
* given namespace.
* *
* See {@link #getSupportedParameterTypes()} to get information relevant to * deciding what parameter types are expected by this method. **
* * @param parameters * an Object[] of parameters for creating ID instances. May be * null. * * @return a non-null ID instance. The class used may extend BaseID or may * implement the ID interface directly * @throws IDCreateException * if construction fails */ public abstract ID createInstance(Object[] parameters) throws IDCreateException; /** * Get the primary scheme associated with this namespace. Subclasses must * provide an implementation that returns a non-null
scheme
* identifier. Note that the returned scheme should not contain the
* Namespace.SCHEME_SEPARATOR (\":\").
*
* @return a String scheme identifier. Must not be null
.
*/
public abstract String getScheme();
/**
* Get an array of schemes supported by this Namespace instance. Subclasses
* may override to support multiple schemes.
*
* @return String[] of schemes supported by this Namespace. Will not be
* null
, but returned array may be of length 0.
*/
public String[] getSupportedSchemes() {
return new String[0];
}
/**
* Get the supported parameter types for IDs created via subsequent calls to
* {@link #createInstance(Object[])}. Callers may use this method to
* determine the available parameter types, and then create and pass in
* conforming Object arrays to to {@link #createInstance(Object[])}.
* *
* An empty two-dimensional array (new Class[0][0]) is the default returned * by this abstract superclass. This means that the Object [] passed to * {@link #createInstance(Object[])} will be ignored. **
* Subsclasses should override this method to specify the parameters that * they will accept in calls to {@link #createInstance(Object[])}. The rows * of the returned Class array are the acceptable types for a given * invocation of createInstance. **
* Consider the following example: **
* ** public Class[][] getSupportedParameterTypes() { * return new Class[][] { { String.class }, { String.class, String.class } }; * } ** * The above means that there are two acceptable values for the Object [] * passed into {@link #createInstance(Object[])}: 1) a single String, and 2) * two Strings. These would therefore be acceptable as input to * createInstance: * *
* ID newID1 = namespace.createInstance(new Object[] { "Hello" }); * ID newID2 = namespace.createInstance(new Object[] { "Hello", "There"}}; ** * @return Class [][] an array of class []s. Rows of the returned * two-dimensional array define the acceptable parameter types for a * single call to {@link #createInstance(Object[])}. If zero-length * Class arrays are returned (i.e. Class[0][0]), then Object [] * parameters to {@link #createInstance(Object[])} will be ignored. */ public Class[][] getSupportedParameterTypes() { return new Class[][] { {} }; } /* * (non-Javadoc) * * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) */ public Object getAdapter(Class adapter) { if (adapter.isInstance(this)) { return this; } IAdapterManager manager = Activator.getDefault().getAdapterManager(); if (manager == null) return null; return manager.loadAdapter(this, adapter.getName()); } protected String getInitStringFromExternalForm(Object[] args) { if (args == null || args.length < 1 || args[0] == null) return null; if (args[0] instanceof String) { final String arg = (String) args[0]; if (arg.startsWith(getScheme() + SCHEME_SEPARATOR)) { final int index = arg.indexOf(SCHEME_SEPARATOR); if (index >= arg.length()) return null; return arg.substring(index + 1); } } return null; } public String toString() { StringBuffer b = new StringBuffer("Namespace["); //$NON-NLS-1$ b.append("name=").append(name).append(";"); //$NON-NLS-1$ //$NON-NLS-2$ b.append("scheme=").append(getScheme()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$ b.append("description=").append("]"); //$NON-NLS-1$ //$NON-NLS-2$ return b.toString(); } }