1 /******************************************************************************* 2 * Copyright (c) 2010, 2013 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.internal.core.project; 15 16 import org.eclipse.core.resources.IContainer; 17 import org.eclipse.core.resources.IFile; 18 import org.eclipse.core.resources.IFolder; 19 import org.eclipse.core.resources.IProject; 20 import org.eclipse.core.resources.ProjectScope; 21 import org.eclipse.core.runtime.CoreException; 22 import org.eclipse.core.runtime.IPath; 23 import org.eclipse.core.runtime.IStatus; 24 import org.eclipse.core.runtime.Path; 25 import org.eclipse.core.runtime.Status; 26 import org.eclipse.core.runtime.preferences.IEclipsePreferences; 27 import org.eclipse.pde.core.plugin.IPluginModelBase; 28 import org.eclipse.pde.core.plugin.PluginRegistry; 29 import org.eclipse.pde.internal.core.ICoreConstants; 30 import org.eclipse.pde.internal.core.PDECore; 31 import org.eclipse.pde.internal.core.PDEManager; 32 import org.osgi.service.prefs.BackingStoreException; 33 34 /** 35 * Utility class to resolve plug-in and bundle files relative to a project 36 * specific bundle root location. 37 * 38 * @since 3.6 39 */ 40 public class PDEProject { 41 42 /** 43 * Preference key for the project relative bundle root path 44 */ 45 public static final String BUNDLE_ROOT_PATH = "BUNDLE_ROOT_PATH"; //$NON-NLS-1$ 46 47 /** 48 * Returns the container in the specified project that corresponds to the 49 * root of bundle related artifacts. May return the project itself 50 * or a folder within the project. 51 * 52 * @param project project 53 * @return container corresponding to the bundle root 54 */ getBundleRoot(IProject project)55 public static IContainer getBundleRoot(IProject project) { 56 ProjectScope scope = new ProjectScope(project); 57 IEclipsePreferences node = scope.getNode(PDECore.PLUGIN_ID); 58 if (node != null) { 59 String string = node.get(BUNDLE_ROOT_PATH, null); 60 if (string != null) { 61 IPath path = Path.fromPortableString(string); 62 return project.getFolder(path); 63 } 64 } 65 return project; 66 } 67 68 /** 69 * Returns the launch shortcuts configured for this project 70 * or <code>null</code> if default launchers should be used. 71 * 72 * @param project project 73 * @return configured launch shortcuts or <code>null</code> 74 */ getLaunchShortcuts(IProject project)75 public static String[] getLaunchShortcuts(IProject project) { 76 ProjectScope scope = new ProjectScope(project); 77 IEclipsePreferences node = scope.getNode(PDECore.PLUGIN_ID); 78 if (node != null) { 79 String list = node.get(ICoreConstants.MANIFEST_LAUNCH_SHORTCUTS, (String) null); 80 if (list != null) { 81 return list.split(","); //$NON-NLS-1$ 82 } 83 } 84 return null; 85 } 86 87 /** 88 * Returns the export wizard configured for this project or <code>null</code> 89 * if default. 90 * 91 * @param project project 92 * @return export wizard identifier or <code>null</code> 93 */ getExportWizard(IProject project)94 public static String getExportWizard(IProject project) { 95 ProjectScope scope = new ProjectScope(project); 96 IEclipsePreferences node = scope.getNode(PDECore.PLUGIN_ID); 97 if (node != null) { 98 return node.get(ICoreConstants.MANIFEST_EXPORT_WIZARD, (String) null); 99 } 100 return null; 101 } 102 103 /** 104 * Sets the root of the bundle related artifacts in the specified project 105 * to the specified container. When <code>null</code> is specified, the 106 * bundle root will be the project itself. The container must be within 107 * the specified project. 108 * 109 * @param project project 110 * @param root project relative bundle root path, or <code>null</code> (or an empty path) 111 * to indicate the root of the bundle is the root of the project 112 * @exception CoreException if unable to set the bundle root to the specified container 113 */ setBundleRoot(IProject project, IContainer root)114 public static void setBundleRoot(IProject project, IContainer root) throws CoreException { 115 if (root != null && !root.getProject().equals(project)) { 116 throw new IllegalArgumentException("root must be contained in the given project"); //$NON-NLS-1$ 117 } 118 ProjectScope scope = new ProjectScope(project); 119 IEclipsePreferences node = scope.getNode(PDECore.PLUGIN_ID); 120 if (node != null) { 121 IPath path = null; 122 if (root != null) { 123 path = root.getProjectRelativePath(); 124 } 125 if (path != null && path.isEmpty()) { 126 path = null; 127 } 128 String value = null; 129 if (path != null) { 130 value = path.toPortableString(); 131 } 132 if (value == null) { 133 node.remove(BUNDLE_ROOT_PATH); 134 } else { 135 node.put(BUNDLE_ROOT_PATH, value); 136 } 137 try { 138 node.flush(); 139 // update model manager 140 PDECore.getDefault().getModelManager().bundleRootChanged(project); 141 } catch (BackingStoreException e) { 142 throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, e.getMessage(), e)); 143 } 144 } else { 145 throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, "Failed to retrieve project scope preference settings")); //$NON-NLS-1$ 146 } 147 } 148 149 /** 150 * Returns the resource in the specified project corresponding to its 151 * <code>MANIFEST.MF</code> file. 152 * 153 * @param project project 154 * @return <code>MANIFEST.MF</code> file that may or may not exist 155 */ getManifest(IProject project)156 public static IFile getManifest(IProject project) { 157 return getBundleRelativeFile(project, ICoreConstants.MANIFEST_PATH); 158 } 159 160 /** 161 * Returns the resource in the specified project corresponding to its 162 * <code>build.properties</code>file. 163 * 164 * @param project project 165 * @return <code>build.properties</code> file that may or may not exist 166 */ getBuildProperties(IProject project)167 public static IFile getBuildProperties(IProject project) { 168 return getBundleRelativeFile(project, ICoreConstants.BUILD_PROPERTIES_PATH); 169 } 170 171 /** 172 * Returns the resource in the specified project corresponding to its 173 * <code>plugin.xml</code>file. 174 * 175 * @param project project 176 * @return <code>plugin.xml</code> file that may or may not exist 177 */ getPluginXml(IProject project)178 public static IFile getPluginXml(IProject project) { 179 return getBundleRelativeFile(project, ICoreConstants.PLUGIN_PATH); 180 } 181 182 /** 183 * Returns the resource in the specified project corresponding to its 184 * <code>fragment.xml</code>file. 185 * 186 * @param project project 187 * @return <code>fragment.xml</code> file that may or may not exist 188 */ getFragmentXml(IProject project)189 public static IFile getFragmentXml(IProject project) { 190 return getBundleRelativeFile(project, ICoreConstants.FRAGMENT_PATH); 191 } 192 193 /** 194 * Returns the resource in the specified project corresponding to its 195 * <code>feature.xml</code>file. 196 * 197 * @param project project 198 * @return <code>feature.xml</code> file that may or may not exist 199 */ getFeatureXml(IProject project)200 public static IFile getFeatureXml(IProject project) { 201 return getBundleRelativeFile(project, ICoreConstants.FEATURE_PATH); 202 } 203 204 /** 205 * Returns the resource in the specified project corresponding to its 206 * <code>.options</code>file. 207 * 208 * @param project project 209 * @return <code>.options</code> file that may or may not exist 210 */ getOptionsFile(IProject project)211 public static IFile getOptionsFile(IProject project) { 212 return getBundleRelativeFile(project, new Path(ICoreConstants.OPTIONS_FILENAME)); 213 } 214 215 /** 216 * Returns the resource in the specified project corresponding to its 217 * <code>OSGI-INF/</code>folder. 218 * 219 * @param project project 220 * @return <code>OSGI-INF/</code> folder that may or may not exist 221 */ getOSGiInf(IProject project)222 public static IFolder getOSGiInf(IProject project) { 223 return getBundleRelativeFolder(project, ICoreConstants.OSGI_INF_PATH); 224 } 225 226 /** 227 * Returns the resource in the specified project corresponding to its 228 * <code>META-INF/</code>folder. 229 * 230 * @param project project 231 * @return <code>META-INF/</code> folder that may or may not exist 232 */ getMetaInf(IProject project)233 public static IFolder getMetaInf(IProject project) { 234 return getBundleRelativeFolder(project, new Path(ICoreConstants.MANIFEST_FOLDER_NAME)); 235 } 236 237 /** 238 * Returns a file relative to the bundle root of the specified project. 239 * 240 * @param project project 241 * @param path bundle root relative path 242 * @return file that may or may not exist 243 */ getBundleRelativeFile(IProject project, IPath path)244 public static IFile getBundleRelativeFile(IProject project, IPath path) { 245 return getBundleRoot(project).getFile(path); 246 } 247 248 /** 249 * Returns a folder relative to the bundle root of the specified project. 250 * 251 * @param project project 252 * @param path bundle root relative path 253 * @return folder that may or may not exist 254 */ getBundleRelativeFolder(IProject project, IPath path)255 public static IFolder getBundleRelativeFolder(IProject project, IPath path) { 256 return getBundleRoot(project).getFolder(path); 257 } 258 259 /** 260 * Returns the bundle localization file for the specified bundle project. 261 * The file may or may not exist. 262 * 263 * @param project 264 * @return bunlde localization file which may or may not exist 265 */ getLocalizationFile(IProject project)266 public static IFile getLocalizationFile(IProject project) { 267 IPluginModelBase model = PluginRegistry.findModel(project); 268 String localization = PDEManager.getBundleLocalization(model); 269 return getBundleRelativeFile(project, new Path(localization + ".properties")); //$NON-NLS-1$ 270 } 271 272 // TODO: schema folder? 273 274 // TODO: plugin_customization.ini ? 275 276 } 277