1 /*******************************************************************************
2  * Copyright (c) 2000, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     Andrey Loskutov <loskutov@gmx.de> - bug 484014
14  *******************************************************************************/
15 package org.eclipse.core.internal.registry;
16 
17 import java.lang.ref.SoftReference;
18 import org.eclipse.core.runtime.IContributor;
19 
20 /**
21  * An object which represents the user-defined extension in a plug-in manifest.
22  */
23 public class Extension extends RegistryObject {
24 	public static final Extension[] EMPTY_ARRAY = new Extension[0];
25 
26 	//Extension simple identifier
27 	private String simpleId;
28 	//The namespace for the extension.
29 	private String namespaceIdentifier;
30 
31 	//	Place holder for the label and  the extension point. It contains either a String[] or a SoftReference to a String[].
32 	//The array layout is [label, extension point name]
33 	private Object extraInformation;
34 	private static final byte LABEL = 0; //The human readable name of the extension
35 	private static final byte XPT_NAME = 1; // The fully qualified name of the extension point to which this extension is attached to
36 	private static final byte CONTRIBUTOR_ID = 2; // ID of the actual contributor of this extension
37 	private static final int EXTRA_SIZE = 3;
38 
Extension(ExtensionRegistry registry, boolean persist)39 	protected Extension(ExtensionRegistry registry, boolean persist) {
40 		super(registry, persist);
41 	}
42 
Extension(int self, String simpleId, String namespace, int[] children, int extraData, ExtensionRegistry registry, boolean persist)43 	protected Extension(int self, String simpleId, String namespace, int[] children, int extraData, ExtensionRegistry registry, boolean persist) {
44 		super(registry, persist);
45 
46 		setObjectId(self);
47 		this.simpleId = simpleId;
48 		setRawChildren(children);
49 		setExtraDataOffset(extraData);
50 		this.namespaceIdentifier = namespace;
51 	}
52 
getExtensionPointIdentifier()53 	protected String getExtensionPointIdentifier() {
54 		String[] extraData = getExtraData();
55 		if (extraData == null) {
56 			return null;
57 		}
58 		return extraData[XPT_NAME];
59 	}
60 
getSimpleIdentifier()61 	protected String getSimpleIdentifier() {
62 		return simpleId;
63 	}
64 
getUniqueIdentifier()65 	protected String getUniqueIdentifier() {
66 		return simpleId == null ? null : this.getNamespaceIdentifier() + '.' + simpleId;
67 	}
68 
setExtensionPointIdentifier(String value)69 	void setExtensionPointIdentifier(String value) {
70 		ensureExtraInformationType();
71 		((String[]) extraInformation)[XPT_NAME] = value;
72 	}
73 
setSimpleIdentifier(String value)74 	void setSimpleIdentifier(String value) {
75 		simpleId = value;
76 	}
77 
getExtraData()78 	private String[] getExtraData() {
79 		//The extension has been created by parsing, or does not have any extra data
80 		if (noExtraData()) {
81 			if (extraInformation != null)
82 				return (String[]) extraInformation;
83 			return null;
84 		}
85 
86 		//The extension has been loaded from the cache.
87 		String[] result = null;
88 		if (extraInformation == null || (result = ((extraInformation instanceof SoftReference) ? (String[]) ((SoftReference<?>) extraInformation).get() : (String[]) extraInformation)) == null) {
89 			result = registry.getTableReader().loadExtensionExtraData(getExtraDataOffset());
90 			extraInformation = new SoftReference<>(result);
91 		}
92 		return result;
93 	}
94 
getLabel()95 	String getLabel() {
96 		String s = getExtraData()[LABEL];
97 		if (s == null)
98 			return ""; //$NON-NLS-1$
99 		return s;
100 	}
101 
setLabel(String value)102 	void setLabel(String value) {
103 		ensureExtraInformationType();
104 		((String[]) extraInformation)[LABEL] = value;
105 	}
106 
getContributorId()107 	String getContributorId() {
108 		String s = getExtraData()[CONTRIBUTOR_ID];
109 		if (s == null)
110 			return ""; //$NON-NLS-1$
111 		return s;
112 	}
113 
getContributor()114 	public IContributor getContributor() {
115 		return registry.getObjectManager().getContributor(getContributorId());
116 	}
117 
setContributorId(String value)118 	void setContributorId(String value) {
119 		ensureExtraInformationType();
120 		((String[]) extraInformation)[CONTRIBUTOR_ID] = value;
121 	}
122 
getNamespaceIdentifier()123 	public String getNamespaceIdentifier() {
124 		return namespaceIdentifier;
125 	}
126 
setNamespaceIdentifier(String value)127 	void setNamespaceIdentifier(String value) {
128 		namespaceIdentifier = value;
129 	}
130 
131 	@Override
toString()132 	public String toString() {
133 		return getUniqueIdentifier() + " -> " + getExtensionPointIdentifier(); //$NON-NLS-1$
134 	}
135 
136 	/**
137 	 * At the end of this method, extra information will be a string[]
138 	 */
ensureExtraInformationType()139 	private void ensureExtraInformationType() {
140 		if (extraInformation instanceof SoftReference) {
141 			extraInformation = ((SoftReference<?>) extraInformation).get();
142 		}
143 		if (extraInformation == null) {
144 			extraInformation = new String[EXTRA_SIZE];
145 		}
146 	}
147 
getLabelAsIs()148 	String getLabelAsIs() {
149 		String s = getExtraData()[LABEL];
150 		if (s == null)
151 			return ""; //$NON-NLS-1$
152 		return s;
153 	}
154 
getLabel(String locale)155 	String getLabel(String locale) {
156 		registry.logMultiLangError();
157 		return getLabel();
158 	}
159 
160 }
161