1 /*******************************************************************************
2  * Copyright (c) 2006, 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 package org.eclipse.osgi.internal.resolver;
16 
17 import java.util.*;
18 import org.eclipse.osgi.service.resolver.*;
19 import org.osgi.framework.Constants;
20 import org.osgi.framework.Version;
21 
22 public class GenericDescriptionImpl extends BaseDescriptionImpl implements GenericDescription {
23 	private Dictionary<String, Object> attributes;
24 	private volatile BundleDescription supplier;
25 	private volatile String type = GenericDescription.DEFAULT_TYPE;
26 	private Map<String, String> directives;
27 	private GenericDescription fragmentDeclaration;
28 
GenericDescriptionImpl()29 	public GenericDescriptionImpl() {
30 		super();
31 	}
32 
GenericDescriptionImpl(BundleDescription host, GenericDescription fragmentDeclaration)33 	public GenericDescriptionImpl(BundleDescription host, GenericDescription fragmentDeclaration) {
34 		setType(fragmentDeclaration.getType());
35 		Dictionary<String, Object> origAttrs = fragmentDeclaration.getAttributes();
36 		if (origAttrs != null) {
37 			Hashtable<String, Object> copyAttrs = new Hashtable<>();
38 			for (Enumeration<String> keys = origAttrs.keys(); keys.hasMoreElements();) {
39 				String key = keys.nextElement();
40 				copyAttrs.put(key, origAttrs.get(key));
41 			}
42 			setAttributes(copyAttrs);
43 		}
44 		Map<String, String> origDirectives = fragmentDeclaration.getDeclaredDirectives();
45 		Map<String, String> copyDirectives = new HashMap<>(origDirectives);
46 		setDirectives(copyDirectives);
47 		setSupplier(host);
48 		this.fragmentDeclaration = fragmentDeclaration;
49 	}
50 
getAttributes()51 	public Dictionary<String, Object> getAttributes() {
52 		synchronized (this.monitor) {
53 			return attributes;
54 		}
55 	}
56 
getSupplier()57 	public BundleDescription getSupplier() {
58 		return supplier;
59 	}
60 
setAttributes(Dictionary<String, Object> attributes)61 	void setAttributes(Dictionary<String, Object> attributes) {
62 		synchronized (this.monitor) {
63 			this.attributes = attributes;
64 		}
65 	}
66 
setDirectives(Map<String, String> directives)67 	void setDirectives(Map<String, String> directives) {
68 		synchronized (this.monitor) {
69 			this.directives = directives;
70 		}
71 	}
72 
setSupplier(BundleDescription supplier)73 	void setSupplier(BundleDescription supplier) {
74 		this.supplier = supplier;
75 	}
76 
77 	@Override
toString()78 	public String toString() {
79 		StringBuilder sb = new StringBuilder();
80 		sb.append(Constants.PROVIDE_CAPABILITY).append(": ").append(getType()); //$NON-NLS-1$
81 		Map<String, Object> attrs = getDeclaredAttributes();
82 		sb.append(toString(attrs, false));
83 		return sb.toString();
84 	}
85 
86 	/**
87 	 * @deprecated
88 	 */
89 	@Override
getName()90 	public String getName() {
91 		synchronized (this.monitor) {
92 			Object name = attributes != null ? attributes.get(getType()) : null;
93 			return name instanceof String ? (String) name : null;
94 		}
95 	}
96 
getType()97 	public String getType() {
98 		return type;
99 	}
100 
setType(String type)101 	void setType(String type) {
102 		if (type == null || type.equals(GenericDescription.DEFAULT_TYPE))
103 			this.type = GenericDescription.DEFAULT_TYPE;
104 		else
105 			this.type = type;
106 	}
107 
108 	/**
109 	 * @deprecated
110 	 */
111 	@Override
getVersion()112 	public Version getVersion() {
113 		Object version = attributes != null ? attributes.get(Constants.VERSION_ATTRIBUTE) : null;
114 		return version instanceof Version ? (Version) version : super.getVersion();
115 	}
116 
getDeclaredDirectives()117 	public Map<String, String> getDeclaredDirectives() {
118 		synchronized (this.monitor) {
119 			if (directives == null)
120 				return Collections.<String, String> emptyMap();
121 			return Collections.unmodifiableMap(directives);
122 		}
123 	}
124 
getDeclaredAttributes()125 	public Map<String, Object> getDeclaredAttributes() {
126 		synchronized (this.monitor) {
127 			Map<String, Object> result = new HashMap<>(5);
128 			if (attributes != null)
129 				for (Enumeration<String> keys = attributes.keys(); keys.hasMoreElements();) {
130 					String key = keys.nextElement();
131 					Object value = attributes.get(key);
132 					if (value instanceof List)
133 						value = Collections.unmodifiableList((List<?>) value);
134 					result.put(key, value);
135 				}
136 			return Collections.unmodifiableMap(result);
137 		}
138 	}
139 
140 	@Override
getInternalNameSpace()141 	String getInternalNameSpace() {
142 		return getType();
143 	}
144 
145 	@Override
getFragmentDeclaration()146 	public BaseDescription getFragmentDeclaration() {
147 		return fragmentDeclaration;
148 	}
149 
setFragmentDeclaration(GenericDescription fragmentDeclaration)150 	void setFragmentDeclaration(GenericDescription fragmentDeclaration) {
151 		this.fragmentDeclaration = fragmentDeclaration;
152 	}
153 }
154