1 /******************************************************************************* 2 * Copyright (c) 2007, 2019 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 *******************************************************************************/ 14 package org.eclipse.pde.core.plugin; 15 16 import java.util.ArrayList; 17 import org.eclipse.core.runtime.PlatformObject; 18 import org.eclipse.osgi.service.resolver.BundleDescription; 19 20 /** 21 * A ModelEntry object has an ID and keeps track of all workspace plug-ins and target 22 * plug-ins that have that ID. 23 * <p> 24 * This class is not meant to be extended or instantiated by clients. 25 * </p> 26 * 27 * @since 3.3 28 * 29 * @noextend This class is not intended to be subclassed by clients. 30 * @noinstantiate This class is not intended to be instantiated by clients. 31 */ 32 public class ModelEntry extends PlatformObject { 33 34 private final String fId; 35 36 /** 37 * The list of workspace models with the same entry ID 38 */ 39 protected ArrayList<IPluginModelBase> fWorkspaceEntries = new ArrayList<>(1); 40 41 /** 42 * The list of external models with the same entry ID 43 */ 44 protected ArrayList<IPluginModelBase> fExternalEntries = new ArrayList<>(1); 45 46 /** 47 * Constructor 48 * 49 * @param id the entry ID 50 */ ModelEntry(String id)51 public ModelEntry(String id) { 52 fId = id; 53 } 54 55 /** 56 * Returns all the workspace plug-ins that have the model entry ID 57 * 58 * @return an array of workspace plug-ins that have the model entry ID 59 */ getWorkspaceModels()60 public IPluginModelBase[] getWorkspaceModels() { 61 return fWorkspaceEntries.toArray(new IPluginModelBase[fWorkspaceEntries.size()]); 62 } 63 64 /** 65 * Returns all plug-ins in the target platform that have the model entry ID. 66 * The returned result contains both plug-ins that are enabled (ie. checked 67 * on the <b>Plug-in Development > Target Platform</b> preference page) 68 * and disabled. 69 * 70 * @return an array of plug-ins in the target platform that have the model 71 * entry ID 72 */ getExternalModels()73 public IPluginModelBase[] getExternalModels() { 74 return fExternalEntries.toArray(new IPluginModelBase[fExternalEntries.size()]); 75 } 76 77 /** 78 * Returns the plug-in model for the best match plug-in with the given ID. 79 * A null value is returned if no such bundle is found in the workspace or target platform. 80 * <p> 81 * A workspace plug-in is always preferably returned over a target plug-in. 82 * A plug-in that is checked/enabled on the Target Platform preference page is always 83 * preferably returned over a target plug-in that is unchecked/disabled. 84 * </p> 85 * <p> 86 * In the case of a tie among workspace plug-ins or among target plug-ins, 87 * the plug-in with the highest version is returned. 88 * </p> 89 * <p> 90 * In the case of a tie among more than one suitable plug-in that have the same version, 91 * one of those plug-ins is randomly returned. 92 * </p> 93 * 94 * @return the plug-in model for the best match plug-in with the given ID 95 */ getModel()96 public IPluginModelBase getModel() { 97 IPluginModelBase model = getBestCandidate(getWorkspaceModels()); 98 if (model == null) { 99 model = getBestCandidate(getExternalModels()); 100 } 101 return model; 102 } 103 getBestCandidate(IPluginModelBase[] models)104 private IPluginModelBase getBestCandidate(IPluginModelBase[] models) { 105 IPluginModelBase result = null; 106 for (IPluginModelBase model : models) { 107 if (model.getBundleDescription() == null) { 108 continue; 109 } 110 111 if (result == null) { 112 result = model; 113 continue; 114 } 115 116 if (!result.isEnabled() && model.isEnabled()) { 117 result = model; 118 continue; 119 } 120 121 BundleDescription current = result.getBundleDescription(); 122 BundleDescription candidate = model.getBundleDescription(); 123 if (!current.isResolved() && candidate.isResolved()) { 124 result = model; 125 continue; 126 } 127 128 if (current.getVersion().compareTo(candidate.getVersion()) < 0) { 129 result = model; 130 } 131 } 132 return result; 133 } 134 135 /** 136 * Returns all the plug-ins, with the model entry ID, that are currently 137 * active. 138 * <p> 139 * Workspace plug-ins are always active. Target plug-ins are only active if: 140 * </p> 141 * <ul> 142 * <li>they are checked on the <b>Plug-in Development > Target 143 * Platform</b> preference page</li> 144 * <li>there does not exist a workspace plug-in that has the same ID</li> 145 * </ul> 146 * 147 * @return an array of the currently active plug-ins with the model entry ID 148 */ getActiveModels()149 public IPluginModelBase[] getActiveModels() { 150 if (!fWorkspaceEntries.isEmpty()) { 151 return getWorkspaceModels(); 152 } 153 154 if (!fExternalEntries.isEmpty()) { 155 ArrayList<IPluginModelBase> list = new ArrayList<>(fExternalEntries.size()); 156 for (int i = 0; i < fExternalEntries.size(); i++) { 157 IPluginModelBase model = fExternalEntries.get(i); 158 if (model.isEnabled()) { 159 list.add(model); 160 } 161 } 162 return list.toArray(new IPluginModelBase[list.size()]); 163 } 164 return new IPluginModelBase[0]; 165 } 166 167 /** 168 * Returns the model entry ID 169 * 170 * @return the model entry ID 171 */ getId()172 public String getId() { 173 return fId; 174 } 175 176 /** 177 * Return the plug-in model associated with the given bundle description or 178 * <code>null</code> if none is found. 179 * 180 * @param desc the given bundle description 181 * 182 * @return the plug-in model associated with the given bundle description if such a 183 * model exists. 184 */ getModel(BundleDescription desc)185 public IPluginModelBase getModel(BundleDescription desc) { 186 if (desc == null) { 187 return null; 188 } 189 190 for (int i = 0; i < fWorkspaceEntries.size(); i++) { 191 IPluginModelBase model = fWorkspaceEntries.get(i); 192 if (desc.equals(model.getBundleDescription())) { 193 return model; 194 } 195 } 196 for (int i = 0; i < fExternalEntries.size(); i++) { 197 IPluginModelBase model = fExternalEntries.get(i); 198 if (desc.equals(model.getBundleDescription())) { 199 return model; 200 } 201 } 202 return null; 203 } 204 205 /** 206 * Returns <code>true</code> if there are workspace plug-ins associated with the ID 207 * of this model entry; <code>false</code>otherwise. 208 * 209 * @return <code>true</code> if there are workspace plug-ins associated with the ID 210 * of this model entry; <code>false</code>otherwise. 211 */ hasWorkspaceModels()212 public boolean hasWorkspaceModels() { 213 return !fWorkspaceEntries.isEmpty(); 214 } 215 216 /** 217 * Returns <code>true</code> if there are target plug-ins associated with the ID 218 * of this model entry; <code>false</code>otherwise. 219 * 220 * @return <code>true</code> if there are target plug-ins associated with the ID 221 * of this model entry; <code>false</code>otherwise. 222 */ hasExternalModels()223 public boolean hasExternalModels() { 224 return !fExternalEntries.isEmpty(); 225 } 226 227 } 228