1 /*******************************************************************************
2  * Copyright (c) 2004, 2016 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  *     Rob Harrop - SpringSource Inc. (bug 247522)
14  *******************************************************************************/
15 
16 package org.eclipse.osgi.internal.resolver;
17 
18 import java.util.*;
19 import org.eclipse.osgi.internal.framework.EquinoxContainer;
20 import org.eclipse.osgi.service.resolver.*;
21 import org.osgi.framework.Constants;
22 import org.osgi.framework.Version;
23 import org.osgi.framework.wiring.BundleRevision;
24 
25 public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements ExportPackageDescription {
26 	public static final String EQUINOX_EE = "x-equinox-ee"; //$NON-NLS-1$
27 	private static final Integer EQUINOX_EE_DEFAULT = Integer.valueOf(-1);
28 	private String[] uses;
29 	private Map<String, Object> attributes;
30 	private Map<String, String> arbitraryDirectives;
31 	private volatile BundleDescription exporter;
32 	private String exclude;
33 	private String include;
34 	private String[] friends;
35 	private String[] mandatory;
36 	private Boolean internal = Boolean.FALSE;
37 	private int equinox_ee = -1;
38 	private ExportPackageDescription fragmentDeclaration = null;
39 
ExportPackageDescriptionImpl()40 	public ExportPackageDescriptionImpl() {
41 		super();
42 	}
43 
ExportPackageDescriptionImpl(BundleDescription host, ExportPackageDescription fragmentDeclaration)44 	public ExportPackageDescriptionImpl(BundleDescription host, ExportPackageDescription fragmentDeclaration) {
45 		setName(fragmentDeclaration.getName());
46 		setVersion(fragmentDeclaration.getVersion());
47 		setDirectives(fragmentDeclaration.getDirectives());
48 		setArbitraryDirectives(((ExportPackageDescriptionImpl) fragmentDeclaration).getArbitraryDirectives());
49 		setAttributes(fragmentDeclaration.getAttributes());
50 		setExporter(host);
51 		this.fragmentDeclaration = fragmentDeclaration;
52 	}
53 
getDirectives()54 	public Map<String, Object> getDirectives() {
55 		synchronized (this.monitor) {
56 			Map<String, Object> result = new HashMap<>(7);
57 			if (uses != null)
58 				result.put(Constants.USES_DIRECTIVE, uses);
59 			if (exclude != null)
60 				result.put(Constants.EXCLUDE_DIRECTIVE, exclude);
61 			if (include != null)
62 				result.put(Constants.INCLUDE_DIRECTIVE, include);
63 			if (mandatory != null)
64 				result.put(Constants.MANDATORY_DIRECTIVE, mandatory);
65 			if (friends != null)
66 				result.put(StateImpl.FRIENDS_DIRECTIVE, friends);
67 			result.put(StateImpl.INTERNAL_DIRECTIVE, internal);
68 			result.put(EQUINOX_EE, equinox_ee == -1 ? EQUINOX_EE_DEFAULT : Integer.valueOf(equinox_ee));
69 			return result;
70 		}
71 	}
72 
getDeclaredDirectives()73 	public Map<String, String> getDeclaredDirectives() {
74 		Map<String, String> result = new HashMap<>(6);
75 		synchronized (this.monitor) {
76 			Map<String, String> arbitrary = getArbitraryDirectives();
77 			if (arbitrary != null)
78 				result.putAll(arbitrary);
79 			if (uses != null)
80 				result.put(Constants.USES_DIRECTIVE, toString(uses));
81 			if (exclude != null)
82 				result.put(Constants.EXCLUDE_DIRECTIVE, exclude);
83 			if (include != null)
84 				result.put(Constants.INCLUDE_DIRECTIVE, include);
85 			if (mandatory != null)
86 				result.put(Constants.MANDATORY_DIRECTIVE, toString(mandatory));
87 			if (friends != null)
88 				result.put(StateImpl.FRIENDS_DIRECTIVE, toString(friends));
89 			if (internal != null)
90 				result.put(StateImpl.INTERNAL_DIRECTIVE, internal.toString());
91 			return Collections.unmodifiableMap(result);
92 		}
93 	}
94 
getDeclaredAttributes()95 	public Map<String, Object> getDeclaredAttributes() {
96 		Map<String, Object> result = new HashMap<>(2);
97 		synchronized (this.monitor) {
98 			if (attributes != null)
99 				result.putAll(attributes);
100 			result.put(BundleRevision.PACKAGE_NAMESPACE, getName());
101 			result.put(Constants.VERSION_ATTRIBUTE, getVersion());
102 			Version bundleVersion = getSupplier().getVersion();
103 			if (bundleVersion != null)
104 				result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
105 			String symbolicName = getSupplier().getSymbolicName();
106 			if (symbolicName != null) {
107 				if (symbolicName.equals(EquinoxContainer.NAME))
108 					result.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, Arrays.asList(Constants.SYSTEM_BUNDLE_SYMBOLICNAME, symbolicName));
109 				else
110 					result.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symbolicName);
111 			}
112 			return Collections.unmodifiableMap(result);
113 		}
114 	}
115 
toString(String[] list)116 	static String toString(String[] list) {
117 		StringBuilder buffer = new StringBuilder();
118 		for (String string : list)
119 			buffer.append(string).append(',');
120 		if (buffer.length() > 0)
121 			buffer.setLength(buffer.length() - 1);
122 		return buffer.toString();
123 	}
124 
getDirective(String key)125 	public Object getDirective(String key) {
126 		synchronized (this.monitor) {
127 			if (key.equals(Constants.USES_DIRECTIVE))
128 				return uses;
129 			if (key.equals(Constants.EXCLUDE_DIRECTIVE))
130 				return exclude;
131 			if (key.equals(Constants.INCLUDE_DIRECTIVE))
132 				return include;
133 			if (key.equals(Constants.MANDATORY_DIRECTIVE))
134 				return mandatory;
135 			if (key.equals(StateImpl.FRIENDS_DIRECTIVE))
136 				return friends;
137 			if (key.equals(StateImpl.INTERNAL_DIRECTIVE))
138 				return internal;
139 			if (key.equals(EQUINOX_EE))
140 				return equinox_ee == -1 ? EQUINOX_EE_DEFAULT : Integer.valueOf(equinox_ee);
141 			return null;
142 		}
143 	}
144 
setDirective(String key, Object value)145 	public Object setDirective(String key, Object value) {
146 		synchronized (this.monitor) {
147 			if (key.equals(Constants.USES_DIRECTIVE))
148 				return uses = (String[]) value;
149 			if (key.equals(Constants.EXCLUDE_DIRECTIVE))
150 				return exclude = (String) value;
151 			if (key.equals(Constants.INCLUDE_DIRECTIVE))
152 				return include = (String) value;
153 			if (key.equals(Constants.MANDATORY_DIRECTIVE))
154 				return mandatory = (String[]) value;
155 			if (key.equals(StateImpl.FRIENDS_DIRECTIVE))
156 				return friends = (String[]) value;
157 			if (key.equals(StateImpl.INTERNAL_DIRECTIVE))
158 				return internal = (Boolean) value;
159 			if (key.equals(EQUINOX_EE)) {
160 				equinox_ee = ((Integer) value).intValue();
161 				return value;
162 			}
163 			return null;
164 		}
165 	}
166 
setDirectives(Map<String, ?> directives)167 	public void setDirectives(Map<String, ?> directives) {
168 		synchronized (this.monitor) {
169 			if (directives == null)
170 				return;
171 			uses = (String[]) directives.get(Constants.USES_DIRECTIVE);
172 			exclude = (String) directives.get(Constants.EXCLUDE_DIRECTIVE);
173 			include = (String) directives.get(Constants.INCLUDE_DIRECTIVE);
174 			mandatory = (String[]) directives.get(Constants.MANDATORY_DIRECTIVE);
175 			friends = (String[]) directives.get(StateImpl.FRIENDS_DIRECTIVE);
176 			internal = (Boolean) directives.get(StateImpl.INTERNAL_DIRECTIVE);
177 			equinox_ee = ((Integer) directives.get(EQUINOX_EE)).intValue();
178 		}
179 	}
180 
181 	@SuppressWarnings("unchecked")
setArbitraryDirectives(Map<String, ?> directives)182 	void setArbitraryDirectives(Map<String, ?> directives) {
183 		synchronized (this.monitor) {
184 			this.arbitraryDirectives = (Map<String, String>) directives;
185 		}
186 	}
187 
getArbitraryDirectives()188 	Map<String, String> getArbitraryDirectives() {
189 		synchronized (this.monitor) {
190 			return arbitraryDirectives;
191 		}
192 	}
193 
getAttributes()194 	public Map<String, Object> getAttributes() {
195 		synchronized (this.monitor) {
196 			return attributes;
197 		}
198 	}
199 
getSupplier()200 	public BundleDescription getSupplier() {
201 		return getExporter();
202 	}
203 
getExporter()204 	public BundleDescription getExporter() {
205 		return exporter;
206 	}
207 
208 	/**
209 	 * @deprecated
210 	 */
isRoot()211 	public boolean isRoot() {
212 		return true;
213 	}
214 
215 	@SuppressWarnings("unchecked")
setAttributes(Map<String, ?> attributes)216 	protected void setAttributes(Map<String, ?> attributes) {
217 		synchronized (this.monitor) {
218 			this.attributes = (Map<String, Object>) attributes;
219 		}
220 	}
221 
setExporter(BundleDescription exporter)222 	protected void setExporter(BundleDescription exporter) {
223 		this.exporter = exporter;
224 	}
225 
226 	@Override
getFragmentDeclaration()227 	public BaseDescription getFragmentDeclaration() {
228 		return fragmentDeclaration;
229 	}
230 
setFragmentDeclaration(ExportPackageDescription fragmentDeclaration)231 	void setFragmentDeclaration(ExportPackageDescription fragmentDeclaration) {
232 		this.fragmentDeclaration = fragmentDeclaration;
233 	}
234 
235 	@Override
toString()236 	public String toString() {
237 		return "Export-Package: " + getName() + "; version=\"" + getVersion() + "\""; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
238 	}
239 
240 	@Override
getInternalNameSpace()241 	String getInternalNameSpace() {
242 		return BundleRevision.PACKAGE_NAMESPACE;
243 	}
244 }
245