Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: c60417a6c3af301c1c6642517817774f343ecb2e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*******************************************************************************
 * Copyright (c) 2011 Wind River Systems, 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:
 * Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.tcf.te.runtime.extensions;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tcf.te.runtime.activator.CoreBundleActivator;
import org.eclipse.tcf.te.runtime.nls.Messages;


/**
 * Executable extension proxy implementation.
 */
public class ExecutableExtensionProxy<V> {
	// The extension instance. Created on first access
	private V instance;
	// The configuration element
	private final IConfigurationElement element;
	// The unique id of the extension.
	private String id;

	/**
	 * Constructor.
	 *
	 * @param element The configuration element. Must not be <code>null</code>.
	 * @throws CoreException In case the configuration element attribute <i>id</i> is <code>null</code> or empty.
	 */
	public ExecutableExtensionProxy(IConfigurationElement element) throws CoreException {
		Assert.isNotNull(element);
		this.element = element;

		// Extract the extension attributes
		id = element.getAttribute("id"); //$NON-NLS-1$
		if (id == null || id.trim().length() == 0) {
			throw new CoreException(new Status(IStatus.ERROR,
					CoreBundleActivator.getUniqueIdentifier(),
					0,
					NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", element.getContributor().getName()), //$NON-NLS-1$
					null));
		}

		instance = null;
	}

	/**
	 * Constructor.
	 *
	 * @param id The id for this instance.
	 * @param instance The instance to add to proxy.
	 */
	public ExecutableExtensionProxy(String id, V instance) {
		Assert.isNotNull(id);
		Assert.isNotNull(instance);
		this.id = id;
		this.instance = instance;
		this.element = null;
	}

	/**
	 * Returns the extensions unique id.
	 *
	 * @return The unique id.
	 */
	public String getId() {
		return id;
	}

	/**
	 * Returns the configuration element for this extension.
	 *
	 * @return The configuration element.
	 */
	public IConfigurationElement getConfigurationElement() {
		return element;
	}

	/**
	 * Reset the extension instance to <code>null</code> and force the
	 * creation of a new extension instance on the next {@link #getInstance()}
	 * method invocation.
	 *
	 * @return The current extension instance or <code>null</code> if none.
	 */
	public V reset() {
		V oldExtension = instance;
		instance = null;
		return oldExtension;
	}

	/**
	 * Returns the extension class instance. The contributing
	 * plug-in will be activated if not yet activated anyway.
	 *
	 * @return The extension class instance or <code>null</code> if the instantiation fails.
	 */
	public V getInstance() {
		if (instance == null) instance = newInstance();
		return instance;
	}

	/**
	 * Returns always a new extension class instance which is different
	 * to what {@link #getInstance()} would return.
	 *
	 * @return A new extension class instance or <code>null</code> if the instantiation fails.
	 */
	public V newInstance() {
		IConfigurationElement element = getConfigurationElement();
		Assert.isNotNull(element);

		// The "class" to load can be specified either as attribute or as child element
		String attributeName = getExecutableExtensionAttributeName();
		Assert.isNotNull(attributeName);
		if (element.getAttribute(attributeName) != null || element.getChildren(attributeName).length > 0) {
			try {
				return (V)element.createExecutableExtension(attributeName);
			} catch (Exception e) {
				// Possible exceptions: CoreException, ClassCastException.
				Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(new Status(IStatus.ERROR,
						CoreBundleActivator.getUniqueIdentifier(),
						NLS.bind(Messages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()), e));
			}
		}
		return null;
	}

	/**
	 * Return the attribute name for the executable extension.
	 */
	protected String getExecutableExtensionAttributeName() {
		return "class"; //$NON-NLS-1$
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		// Proxie's are equal if they have encapsulate an element
		// with the same unique id
		if (obj instanceof ExecutableExtensionProxy<?>) {
			return getId().equals(((ExecutableExtensionProxy<?>)obj).getId());
		}
		return super.equals(obj);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		// The hash code of a proxy is the one from the id
		return getId().hashCode();
	}
}

Back to the top