001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.commands;
011:
012: import org.eclipse.core.commands.IParameter;
013: import org.eclipse.core.commands.IParameterValues;
014: import org.eclipse.core.commands.ITypedParameter;
015: import org.eclipse.core.commands.ParameterType;
016: import org.eclipse.core.commands.ParameterValuesException;
017: import org.eclipse.core.commands.common.HandleObject;
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.core.runtime.IConfigurationElement;
020: import org.eclipse.ui.internal.util.Util;
021:
022: /**
023: * <p>
024: * A parameter for a command. A parameter identifies a type of information that
025: * the command might accept. For example, a "Show View" command might accept the
026: * id of a view for display. This parameter also identifies possible values, for
027: * display in the user interface.
028: * </p>
029: * <p>
030: * Parameters are mutable, and can change as the command changes. Notifications
031: * will not be sent if the parameter itself changes. Listeners can be attached
032: * to the command.
033: * </p>
034: *
035: * @since 3.1
036: */
037: public final class Parameter implements IParameter, ITypedParameter {
038:
039: /**
040: * The name of the configuration element attribute contain the values. This
041: * is used to retrieve the executable extension
042: * <code>IParameterValues</code>.
043: */
044: private static final String ATTRIBUTE_VALUES = "values"; //$NON-NLS-1$
045:
046: /**
047: * The constant integer hash code value meaning the hash code has not yet
048: * been computed.
049: */
050: private static final int HASH_CODE_NOT_COMPUTED = -1;
051:
052: /**
053: * A factor for computing the hash code for all schemes.
054: */
055: private static final int HASH_FACTOR = 89;
056:
057: /**
058: * The seed for the hash code for all schemes.
059: */
060: private static final int HASH_INITIAL = HandleObject.class
061: .getName().hashCode();
062:
063: /**
064: * The hash code for this object. This value is computed lazily, and marked
065: * as invalid when one of the values on which it is based changes.
066: */
067: private transient int hashCode = HASH_CODE_NOT_COMPUTED;
068:
069: /**
070: * The identifier for this object. This identifier should be unique across
071: * all objects of the same type and should never change. This value will
072: * never be <code>null</code>.
073: */
074: protected final String id;
075:
076: /**
077: * The non-externalized name of this parameter. The name is used as the in a
078: * name-value parameter map. This value will never be <code>null</code>.
079: */
080: private final String name;
081:
082: /**
083: * Whether the parameter is optional (as opposed to required).
084: */
085: private final boolean optional;
086:
087: /**
088: * The type for this parameter. This value may be <code>null</code> if the
089: * parameter is not typed.
090: */
091: private final ParameterType parameterType;
092:
093: /**
094: * The string representation of this object. This string is for debugging
095: * purposes only, and is not meant to be displayed to the user. This value
096: * is computed lazily, and is cleared if one of its dependent values
097: * changes.
098: */
099: protected transient String string = null;
100:
101: /**
102: * The actual <code>IParameterValues</code> implementation. This is lazily
103: * loaded from the <code>valuesConfigurationElement</code>, to avoid
104: * unnecessary class-loading.
105: */
106: private transient IParameterValues values = null;
107:
108: /**
109: * The configuration element providing the executable extension that will
110: * implement <code>IParameterValues</code>. This value will not be
111: * <code>null</code>.
112: */
113: private final IConfigurationElement valuesConfigurationElement;
114:
115: /**
116: * Constructs a new instance of <code>Parameter</code> with all of its
117: * values pre-defined.
118: *
119: * @param id
120: * The identifier for this parameter; must not be
121: * <code>null</code>.
122: * @param name
123: * The name for this parameter; must not be <code>null</code>.
124: * @param values
125: * The values for this parameter; must not be <code>null</code>.
126: * @param parameterType
127: * the type for this parameter; may be <code>null</code> if the
128: * parmeter doesn't declare type.
129: * @param optional
130: * Whether this parameter is optional (as opposed to required).
131: * @param commandService
132: * The command service from which parameter types can be
133: * retrieved; must not be <code>null</code>.
134: */
135: public Parameter(final String id, final String name,
136: final IConfigurationElement values,
137: final ParameterType parameterType, final boolean optional) {
138: if (id == null) {
139: throw new NullPointerException(
140: "Cannot create a parameter with a null id"); //$NON-NLS-1$
141: }
142:
143: if (name == null) {
144: throw new NullPointerException(
145: "The name of a parameter cannot be null."); //$NON-NLS-1$
146: }
147:
148: if (values == null) {
149: throw new NullPointerException(
150: "The values for a parameter cannot be null."); //$NON-NLS-1$
151: }
152:
153: this .id = id;
154: this .name = name;
155: this .valuesConfigurationElement = values;
156: this .parameterType = parameterType;
157: this .optional = optional;
158: }
159:
160: /**
161: * Tests whether this object is equal to another object. A parameter is only
162: * equal to another parameter with the same properties.
163: *
164: * @param object
165: * The object with which to compare; may be <code>null</code>.
166: * @return <code>true</code> if the objects are equal; <code>false</code>
167: * otherwise.
168: */
169: public final boolean equals(final Object object) {
170: if (this == object) {
171: return true;
172: }
173:
174: if (!(object instanceof Parameter)) {
175: return false;
176: }
177:
178: final Parameter parameter = (Parameter) object;
179: if (!Util.equals(id, parameter.id)) {
180: return false;
181: }
182: if (!Util.equals(name, parameter.name)) {
183: return false;
184: }
185: if (!Util.equals(values, parameter.values)) {
186: return false;
187: }
188:
189: return Util.equals(optional, parameter.optional);
190: }
191:
192: public final String getId() {
193: return id;
194: }
195:
196: public final String getName() {
197: return name;
198: }
199:
200: public final ParameterType getParameterType() {
201: return parameterType;
202: }
203:
204: public final IParameterValues getValues()
205: throws ParameterValuesException {
206: if (values == null) {
207: try {
208: values = (IParameterValues) valuesConfigurationElement
209: .createExecutableExtension(ATTRIBUTE_VALUES);
210: } catch (final CoreException e) {
211: throw new ParameterValuesException(
212: "Problem creating parameter values", e); //$NON-NLS-1$
213: } catch (final ClassCastException e) {
214: throw new ParameterValuesException(
215: "Parameter values were not an instance of IParameterValues", e); //$NON-NLS-1$
216: }
217: }
218:
219: return values;
220: }
221:
222: public final int hashCode() {
223: if (hashCode == HASH_CODE_NOT_COMPUTED) {
224: hashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(id);
225: if (hashCode == HASH_CODE_NOT_COMPUTED) {
226: hashCode++;
227: }
228: }
229: return hashCode;
230: }
231:
232: public final boolean isOptional() {
233: return optional;
234: }
235:
236: public final String toString() {
237: if (string == null) {
238: final StringBuffer buffer = new StringBuffer();
239:
240: buffer.append("Parameter("); //$NON-NLS-1$
241: buffer.append(id);
242: buffer.append(',');
243: buffer.append(name);
244: buffer.append(',');
245: buffer.append(values);
246: buffer.append(',');
247: buffer.append(optional);
248: buffer.append(')');
249:
250: string = buffer.toString();
251: }
252:
253: return string;
254: }
255: }
|