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 package org.eclipse.osgi.internal.resolver; 16 17 import java.util.*; 18 import java.util.Map.Entry; 19 import org.eclipse.osgi.service.resolver.BaseDescription; 20 import org.osgi.framework.Version; 21 import org.osgi.framework.wiring.BundleCapability; 22 import org.osgi.framework.wiring.BundleRevision; 23 24 public abstract class BaseDescriptionImpl implements BaseDescription { 25 26 protected final Object monitor = new Object(); 27 28 private volatile String name; 29 30 private volatile Version version; 31 32 private volatile Object userObject; 33 getName()34 public String getName() { 35 return name; 36 } 37 getVersion()38 public Version getVersion() { 39 synchronized (this.monitor) { 40 if (version == null) 41 return Version.emptyVersion; 42 return version; 43 } 44 } 45 setName(String name)46 protected void setName(String name) { 47 this.name = name; 48 } 49 setVersion(Version version)50 protected void setVersion(Version version) { 51 this.version = version; 52 } 53 toString(Map<String, V> map, boolean directives)54 static <V> String toString(Map<String, V> map, boolean directives) { 55 if (map.size() == 0) 56 return ""; //$NON-NLS-1$ 57 String assignment = directives ? ":=" : "="; //$NON-NLS-1$//$NON-NLS-2$ 58 Set<Entry<String, V>> set = map.entrySet(); 59 StringBuilder sb = new StringBuilder(); 60 for (Entry<String, V> entry : set) { 61 sb.append("; "); //$NON-NLS-1$ 62 String key = entry.getKey(); 63 Object value = entry.getValue(); 64 if (value instanceof List) { 65 @SuppressWarnings("unchecked") 66 List<Object> list = (List<Object>) value; 67 if (list.size() == 0) 68 continue; 69 Object component = list.get(0); 70 String className = component.getClass().getName(); 71 String type = className.substring(className.lastIndexOf('.') + 1); 72 sb.append(key).append(':').append("List<").append(type).append(">").append(assignment).append('"'); //$NON-NLS-1$ //$NON-NLS-2$ 73 for (Object object : list) 74 sb.append(object).append(','); 75 sb.setLength(sb.length() - 1); 76 sb.append('"'); 77 } else { 78 String type = ""; //$NON-NLS-1$ 79 if (!(value instanceof String)) { 80 String className = value.getClass().getName(); 81 type = ":" + className.substring(className.lastIndexOf('.') + 1); //$NON-NLS-1$ 82 } 83 sb.append(key).append(type).append(assignment).append('"').append(value).append('"'); 84 } 85 } 86 return sb.toString(); 87 } 88 getInternalNameSpace()89 String getInternalNameSpace() { 90 return null; 91 } 92 getFragmentDeclaration()93 public BaseDescription getFragmentDeclaration() { 94 return null; 95 } 96 getCapability()97 public BundleCapability getCapability() { 98 return getCapability(null); 99 } 100 getCapability(String namespace)101 BundleCapability getCapability(String namespace) { 102 BaseDescriptionImpl fragmentDeclaration = (BaseDescriptionImpl) getFragmentDeclaration(); 103 if (fragmentDeclaration != null) 104 return fragmentDeclaration.getCapability(namespace); 105 if (namespace == null) 106 namespace = getInternalNameSpace(); 107 if (namespace == null) 108 return null; 109 return new BaseCapability(namespace); 110 } 111 getUserObject()112 public Object getUserObject() { 113 return userObject; 114 } 115 setUserObject(Object userObject)116 public void setUserObject(Object userObject) { 117 this.userObject = userObject; 118 } 119 120 public class BaseCapability implements BundleCapability { 121 private final String namespace; 122 BaseCapability(String namespace)123 public BaseCapability(String namespace) { 124 super(); 125 this.namespace = namespace; 126 } 127 getRevision()128 public BundleRevision getRevision() { 129 return getSupplier(); 130 } 131 getNamespace()132 public String getNamespace() { 133 return namespace; 134 } 135 getDirectives()136 public Map<String, String> getDirectives() { 137 return getDeclaredDirectives(); 138 } 139 getAttributes()140 public Map<String, Object> getAttributes() { 141 Map<String, Object> attrs = getDeclaredAttributes(); 142 String internalName = BaseDescriptionImpl.this.getInternalNameSpace(); 143 if (namespace.equals(internalName)) 144 return attrs; 145 // we are doing an alias, must remove internal Name and add alias 146 attrs = new HashMap<>(attrs); 147 Object nameValue = attrs.remove(internalName); 148 if (nameValue != null) 149 attrs.put(namespace, nameValue); 150 return Collections.unmodifiableMap(attrs); 151 } 152 153 @Override hashCode()154 public int hashCode() { 155 return System.identityHashCode(BaseDescriptionImpl.this); 156 } 157 getBaseDescription()158 public BaseDescriptionImpl getBaseDescription() { 159 return BaseDescriptionImpl.this; 160 } 161 162 @Override equals(Object obj)163 public boolean equals(Object obj) { 164 if (this == obj) 165 return true; 166 if (!(obj instanceof BaseCapability)) 167 return false; 168 return (((BaseCapability) obj).getBaseDescription() == BaseDescriptionImpl.this) && namespace.equals(((BaseCapability) obj).getNamespace()); 169 } 170 171 @Override toString()172 public String toString() { 173 return getNamespace() + BaseDescriptionImpl.toString(getAttributes(), false) + BaseDescriptionImpl.toString(getDirectives(), true); 174 } 175 getResource()176 public BundleRevision getResource() { 177 return getRevision(); 178 } 179 } 180 } 181