Java tutorial
/******************************************************************************* * Copyright (c) 2009, 2016 Xored Software Inc and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Xored Software Inc - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.rcptt.launching.internal.target; import static com.google.common.base.Charsets.UTF_8; import static java.util.Collections.emptyList; import static org.eclipse.rcptt.internal.launching.ext.Q7ExtLaunchingPlugin.PLUGIN_ID; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.emf.common.util.EList; import org.eclipse.equinox.frameworkadmin.BundleInfo; import org.eclipse.equinox.internal.simpleconfigurator.utils.SimpleConfiguratorUtils; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.query.IQuery; import org.eclipse.equinox.p2.query.IQueryResult; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.environments.IExecutionEnvironment; import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager; import org.eclipse.osgi.service.resolver.ResolverError; import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.core.target.ITargetDefinition; import org.eclipse.pde.core.target.ITargetLocation; import org.eclipse.pde.core.target.ITargetPlatformService; import org.eclipse.pde.core.target.TargetBundle; import org.eclipse.pde.internal.core.PDECore; import org.eclipse.pde.internal.core.PDEExtensionRegistry; import org.eclipse.pde.internal.core.PDEState; import org.eclipse.pde.internal.core.target.DirectoryBundleContainer; import org.eclipse.pde.internal.core.target.IUBundleContainer; import org.eclipse.pde.internal.core.target.P2TargetUtils; import org.eclipse.pde.internal.core.target.ProfileBundleContainer; import org.eclipse.pde.internal.launching.launcher.LaunchValidationOperation; import org.eclipse.rcptt.internal.launching.Q7LaunchingPlugin; import org.eclipse.rcptt.internal.launching.ext.AJConstants; import org.eclipse.rcptt.internal.launching.ext.OSArchitecture; import org.eclipse.rcptt.internal.launching.ext.Q7ExtLaunchingPlugin; import org.eclipse.rcptt.launching.ext.AUTInformation; import org.eclipse.rcptt.launching.ext.OriginalOrderProperties; import org.eclipse.rcptt.launching.ext.Q7LaunchDelegateUtils; import org.eclipse.rcptt.launching.injection.Directory; import org.eclipse.rcptt.launching.injection.Entry; import org.eclipse.rcptt.launching.injection.InjectionConfiguration; import org.eclipse.rcptt.launching.injection.UpdateSite; import org.eclipse.rcptt.launching.internal.target.Q7Target.AutInstall; import org.eclipse.rcptt.launching.p2utils.P2Utils; import org.eclipse.rcptt.launching.target.ITargetPlatformHelper; import org.eclipse.rcptt.launching.target.TargetPlatformManager; import org.eclipse.rcptt.util.FileUtil; import org.osgi.framework.Version; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import com.google.common.io.Files; @SuppressWarnings("restriction") public class TargetPlatformHelper implements ITargetPlatformHelper { public static final String IDE_APPLICATION = "org.eclipse.ui.ide.workbench"; public static final String APPLICATION_PROPERTY = "eclipse.application"; //$NON-NLS-1$ public static final String PRODUCT_PROPERTY = "eclipse.product"; //$NON-NLS-1$ private static final String ID_PROPERTY = "id"; //$NON-NLS-1$ private static final String OSGI_BUNDLES = "osgi.bundles"; public static final String SIMPLECONFIGURATOR = "org.eclipse.equinox.simpleconfigurator"; //$NON-NLS-1$ private static final String SC_BUNDLES_PATH = "configuration/org.eclipse.equinox.simpleconfigurator/bundles.info"; //$NON-NLS-1$ private IStatus status = Status.OK_STATUS; private final ITargetDefinition target; private final ArrayList<ITargetLocation> extra = new ArrayList<ITargetLocation>(); private IPluginModelBase[] models; private PDEExtensionRegistry registry; private Q7Target q7target = new Q7Target(); public TargetPlatformHelper(ITargetDefinition target) { Preconditions.checkNotNull(target); this.target = target; initialize(); } public Q7Target getQ7Target() { return q7target; } @Deprecated /** Use getStatus().isOK() instead */ public boolean isValid() { return getStatus().isOK(); } public boolean isResolved() { if (target != null) { return target.isResolved(); } return false; } public boolean isInstanceContainerValid() { return getInstanceContainer() != null && getInstanceContainer().getStatus().isOK(); } public IStatus getStatus() { if (status == null) { return new Status(IStatus.ERROR, PLUGIN_ID, "Target platform is unset"); } return status; } @Deprecated public String getErrorMessage() { return getNonMultiStatusMessage(getStatus()); } public String getWarningMessage() { if (target != null) { IStatus bundleStatus = getBundleWarningStatus(); return getNonMultiStatusMessage(bundleStatus); } return null; } public IStatus getBundleStatus() { ITargetLocation[] containers = getBundleContainers(); if (containers != null) { // Check if the containers have any resolution problems MultiStatus result = new MultiStatus(PDECore.PLUGIN_ID, 0, org.eclipse.pde.internal.core.target.Messages.TargetDefinition_5, null); for (int i = 0; i < containers.length; i++) { ITargetLocation container = containers[i]; IStatus containerStatus = container.getStatus(); if (containerStatus != null && !containerStatus.isOK()) { result.add(containerStatus); } } if (!result.isOK()) { return result; } // Check if any of the included bundles have problems // build status from bundle list TargetBundle[] bundles = target.getBundles(); for (int i = 0; i < bundles.length; i++) { TargetBundle bundle = bundles[i]; if (!bundle.getStatus().isOK()) { BundleInfo info = bundle.getBundleInfo(); URI uri = info.getLocation(); if (uri != null) { File file = new File(uri); if (!file.exists()) { reportUnexistingFile(info); continue; } } result.add(bundle.getStatus()); } } if (result.isOK()) { // Return generic ok status instead of problem multi-status with // no children return Status.OK_STATUS; } return result; } return Status.OK_STATUS; } private void reportUnexistingFile(BundleInfo info) { // Skip problem of nonexistent file. Q7LaunchingPlugin.log(Q7LaunchingPlugin.createStatus(IStatus.WARNING, "Skip nonexistent bundle: " + info.getSymbolicName() + ", then resolve configuration.", null)); } public IStatus getBundleWarningStatus() { ITargetLocation[] containers = getBundleContainers(); if (containers != null) { // Check if the containers have any resolution problems MultiStatus result = new MultiStatus(PDECore.PLUGIN_ID, 0, org.eclipse.pde.internal.core.target.Messages.TargetDefinition_5, null); // Check if any of the included bundles have problems // build status from bundle list TargetBundle[] bundles = target.getBundles(); for (int i = 0; i < bundles.length; i++) { TargetBundle bundle = bundles[i]; IStatus status = bundle.getStatus(); if (!status.isOK()) { BundleInfo info = bundle.getBundleInfo(); URI uri = info.getLocation(); if (uri != null) { File file = new File(uri); if (!file.exists()) { // Skip problem of nonexistent file. IStatus st = new Status(IStatus.WARNING, status.getPlugin(), status.getMessage(), status.getException()); result.add(st); } } } } if (result.isOK()) { // Return generic ok status instead of problem multi-status with // no children return Status.OK_STATUS; } return result; } return Status.OK_STATUS; } private String getNonMultiStatusMessage(IStatus st) { if (st != null && st.isMultiStatus()) { StringBuilder buf = new StringBuilder(); IStatus[] children = st.getChildren(); for (IStatus iStatus : children) { if (iStatus.isMultiStatus()) { String msg = getNonMultiStatusMessage(iStatus); if (msg != null) { buf.append(msg).append('\n'); } } if (!iStatus.isOK()) { buf.append(iStatus.getMessage()).append('\n'); } } return buf.toString(); } return st == null ? "" : st.getMessage(); } private void initialize() { extra.clear(); q7target = new Q7Target(); if (this.target != null && this.target.getTargetLocations() != null) { ITargetLocation[] containers = this.target.getTargetLocations(); for (ITargetLocation iUBundleContainer : containers) { if (iUBundleContainer instanceof ProfileBundleContainer) { getQ7Target().setInstall(iUBundleContainer); } else if (iUBundleContainer instanceof DirectoryBundleContainer) { getQ7Target().pluginsDir = iUBundleContainer; } else { getQ7Target().addExtra(iUBundleContainer); } extra.add(iUBundleContainer); } } } public void setTargetName(String name) { if (target != null) { target.setName(name); } } public String getName() { if (target != null) { return target.getName(); } return ""; } public void save() throws CoreException { if (!getStatus().isOK()) throw new CoreException(getStatus()); // Remove previous target platforms with same name. TargetPlatformManager.deleteTargetPlatform(target.getName()); try { ITargetPlatformService service = PDEHelper.getTargetService(); service.saveTargetDefinition(target); } catch (CoreException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } } public String getTargetPlatformProfilePath() { ProfileBundleContainer container = (ProfileBundleContainer) getInstanceContainer(); if (container == null) { return ""; } try { return container.getLocation(true).toString(); } catch (CoreException e) { throw new RuntimeException(e); } } public void delete() { try { if (target != null && target.getHandle() != null) { PDEHelper.getTargetService().deleteTarget(target.getHandle()); } } catch (CoreException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } } public ITargetDefinition getTarget() { return target; } public void update() { List<ITargetLocation> newContainers = new ArrayList<ITargetLocation>(); newContainers.addAll(Arrays.asList(target.getTargetLocations())); if (extra != null) { newContainers.addAll(extra); } target.setTargetLocations(newContainers.toArray(new ITargetLocation[newContainers.size()])); models = null; registry = null; } private IPluginModelBase[] getTargetModels() { calcModels(); return models; } @Override public IPluginModelBase getWeavingHook() { calcModels(); return weavingHook; } private void calcModels() { if (models == null) { List<IPluginModelBase> bundles = sumBundles(); weavingHook = filterHooks(bundles); models = bundles.toArray(new IPluginModelBase[0]); } } private List<IPluginModelBase> sumBundles() { TargetBundle[] bundles = getTarget().getAllBundles(); if (bundles == null) { return new ArrayList<IPluginModelBase>(); } List<URL> urls = new ArrayList<URL>(); for (TargetBundle bundle : bundles) { try { urls.add(new URL("file://" + bundle.getBundleInfo().getLocation().getPath())); } catch (MalformedURLException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } } PDEState state = new PDEState(urls.toArray(new URL[urls.size()]), true, true, new NullProgressMonitor()); return new ArrayList<IPluginModelBase>(Arrays.asList(state.getTargetModels())); } private IPluginModelBase filterHooks(List<IPluginModelBase> models) { List<IPluginModelBase> hooks = new ArrayList<IPluginModelBase>(); for (IPluginModelBase model : models) { String name = model.getBundleDescription().getSymbolicName(); if (Objects.equal(name, AJConstants.HOOK)) { hooks.add(model); } } switch (hooks.size()) { case 0: // no weaving hook return null; case 1: // one weaving hook, nothing to filter return hooks.get(0); default: // find a hook with the latest version, remove other hooks IPluginModelBase maxHook = hooks.get(0); for (int i = 1; i < hooks.size(); i++) { IPluginModelBase hook = hooks.get(i); if (hook.getBundleDescription().getVersion() .compareTo(maxHook.getBundleDescription().getVersion()) > 0) { maxHook = hook; } } hooks.remove(maxHook); models.removeAll(hooks); return maxHook; } } private IPluginModelBase weavingHook; @SuppressWarnings({ "rawtypes", "unchecked" }) private IStatus validateBundles(IProgressMonitor monitor) { LaunchValidationOperation validation = new LaunchValidationOperation(null) { @Override protected IPluginModelBase[] getModels() throws CoreException { return getTargetModels(); } @Override protected IExecutionEnvironment[] getMatchingEnvironments() throws CoreException { IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager(); IExecutionEnvironment[] envs = manager.getExecutionEnvironments(); return envs; } }; try { StringBuilder b = new StringBuilder(); validation.run(monitor); Map input = validation.getInput(); Set<Map.Entry> entrySet = input.entrySet(); for (Map.Entry e : entrySet) { Object value = e.getKey(); if (value instanceof ResolverError) { b.append(value.toString()).append("\n"); } } if (b.length() > 0) { return new Status(IStatus.ERROR, PLUGIN_ID, "Bundle validation failed: " + b.toString()); } } catch (CoreException e) { Q7ExtLaunchingPlugin.getDefault().log(e); return status = e.getStatus(); } catch (OperationCanceledException e) { return status = Status.CANCEL_STATUS; } return status = Status.OK_STATUS; } public String[] getProducts() { if (!isValid()) { return new String[0]; } PDEExtensionRegistry reg = getRegistry(); Set<String> result = new TreeSet<String>(); IExtension[] extensions = reg.findExtensions("org.eclipse.core.runtime.products", false); //$NON-NLS-1$ for (int i = 0; i < extensions.length; i++) { IConfigurationElement[] elements = extensions[i].getConfigurationElements(); if (elements.length != 1) continue; if (!"product".equals(elements[0].getName())) //$NON-NLS-1$ continue; String id = extensions[i].getUniqueIdentifier(); if (id != null && id.trim().length() > 0) result.add(id); } return result.toArray(new String[result.size()]); } public String[] getApplications() { if (!isValid()) { return new String[0]; } PDEExtensionRegistry reg = getRegistry(); Set<String> result = new TreeSet<String>(); IExtension[] extensions = reg.findExtensions("org.eclipse.core.runtime.applications", false); //$NON-NLS-1$ for (int i = 0; i < extensions.length; i++) { String id = extensions[i].getUniqueIdentifier(); IConfigurationElement[] elements = extensions[i].getConfigurationElements(); if (elements.length != 1) continue; String visiblity = elements[0].getAttribute("visible"); //$NON-NLS-1$ boolean visible = visiblity == null ? true : Boolean.valueOf(visiblity).booleanValue(); if (id != null && visible) { result.add(id); } } // result.add(IDE_APPLICATION); //$NON-NLS-1$ return result.toArray(new String[result.size()]); } private PDEExtensionRegistry getRegistry() { if (registry == null) { registry = new PDEExtensionRegistry(getTargetModels()); } return registry; } public IStatus resolve(IProgressMonitor monitor) { ITargetDefinition target = getTarget(); if (target != null) { SubMonitor m = SubMonitor.convert(monitor, "Resolving " + getName(), 2); try { status = target.resolve(m.newChild(1, SubMonitor.SUPPRESS_NONE)); if (!status.isOK()) return status; status = validateBundles(m.newChild(1, SubMonitor.SUPPRESS_NONE)); if (!status.isOK()) return status; return status = getBundleStatus(); } finally { m.done(); } } return status = Status.CANCEL_STATUS; } public OriginalOrderProperties getConfigIniProperties() { File iniFile = new File(getTargetPlatformProfilePath(), "configuration/config.ini"); //$NON-NLS-1$ OriginalOrderProperties pini = new OriginalOrderProperties(); if (!iniFile.exists()) return pini; FileInputStream fis = null; try { fis = new FileInputStream(iniFile); pini.load(fis); fis.close(); return pini; } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } finally { try { if (fis != null) fis.close(); } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } } return pini; } protected String getEclipseProductFileProperty(String name) { Properties props = getEclipseProductFileProperties(); return props == null ? null : props.getProperty(name); } public Properties getEclipseProductFileProperties() { File iniFile = new File(getTargetPlatformProfilePath(), ".eclipseproduct"); //$NON-NLS-1$ if (!iniFile.exists()) return null; Properties pini = new Properties(); FileInputStream fis = null; try { fis = new FileInputStream(iniFile); pini.load(fis); fis.close(); return pini; } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } finally { try { if (fis != null) fis.close(); } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } } return null; } public String getDefaultApplication() { String app = getConfigIniProperty(APPLICATION_PROPERTY); HashSet<String> apps = new HashSet<String>(Arrays.asList(getApplications())); return isValidId(app, apps) ? app : (isValidId(IDE_APPLICATION, apps) ? IDE_APPLICATION : null); } public String getBundlesList() { String bundles = getConfigIniProperty(OSGI_BUNDLES); return bundles == null ? org.eclipse.pde.internal.core.TargetPlatformHelper.getDefaultBundleList() : org.eclipse.pde.internal.core.TargetPlatformHelper.stripPathInformation(bundles); } protected String getConfigIniProperty(String name) { Properties config = getConfigIniProperties(); if (config == null) { return null; } return config.getProperty(name); } protected boolean isValidId(String id, Set<String> available) { return id == null ? false : available.contains(id); } public String getDefaultProduct() { Set<String> values = new HashSet<String>(Arrays.asList(getProducts())); String product = null; String productProperty = getConfigIniProperty(PRODUCT_PROPERTY); if (isValidId(productProperty, values)) { product = productProperty; } // Try to load .eclipseproduct file productProperty = getEclipseProductFileProperty(ID_PROPERTY); if (isValidId(productProperty, values)) { product = productProperty; } // Try to load from application ini file List<File> iniFiles = getAppIniFiles(); for (File file : iniFiles) { productProperty = readProductFromIniFile(file); if (isValidId(productProperty, values)) { product = productProperty; } } return product; } public ITargetLocation[] getBundleContainers() { if (target == null) { return new ITargetLocation[0]; } ITargetLocation[] bundleContainers = target.getTargetLocations(); if (bundleContainers == null) { return new ITargetLocation[0]; } return bundleContainers; } // Repository for all update site injections @SuppressWarnings("unused") private IFileArtifactRepository repository; public IStatus applyInjection(InjectionConfiguration configuration, IProgressMonitor monitor) { // remove the "host" from bundles, it is handled in a separate, special // way Iterables.removeAll(extra, Arrays.asList(getInstanceContainer())); EList<Entry> entries = configuration.getEntries(); monitor.beginTask("Apply injection plugins", 20 + entries.size() * 20); for (Entry entry : entries) { SubProgressMonitor mon = new SubProgressMonitor(monitor, 20); if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } IStatus result = new Status(IStatus.ERROR, PLUGIN_ID, "Unknown injection type: " + entry.getClass().getName()); if (entry instanceof UpdateSite) { result = processUpdateSite(mon, (UpdateSite) entry); } else if (entry instanceof Directory) { result = processDirectory((Directory) entry); } if (result.matches(IStatus.ERROR | IStatus.CANCEL)) { return result; } } update(); IStatus resolveStatus = resolve(monitor); if (!resolveStatus.isOK()) { return resolveStatus; } if (getWeavingHook() == null) { return status = createError("No org.eclipse.weaving hook plugin"); } try { save(); } catch (CoreException e) { return e.getStatus(); } return Status.OK_STATUS; } private IStatus processDirectory(Directory entry) { String path = entry.getPath(); MultiStatus rv = new MultiStatus(PLUGIN_ID, 0, "Processing " + path, null); if (path.startsWith("platform:///")) { // if path is platform uri, lets resolve it to file try { URL resolve = FileLocator.resolve(URI.create(path).toURL()); path = resolve.getPath(); } catch (MalformedURLException e) { rv.add(new Status(IStatus.WARNING, PLUGIN_ID, e.getMessage(), e)); } catch (IOException e) { rv.add(new Status(IStatus.WARNING, PLUGIN_ID, e.getMessage(), e)); } } ITargetLocation container = PDEHelper.getTargetService().newDirectoryLocation(path); q7target.addExtra(container); extra.add(container); return Status.OK_STATUS; } private static final IStatus createError(String message) { return createError(message, null); } private static final IStatus createError(String message, Throwable error) { if (message == null && error != null) { message = error.getMessage(); } return new Status(IStatus.ERROR, PLUGIN_ID, message, error); } private IStatus processUpdateSite(IProgressMonitor monitor, UpdateSite site) { try { URI uri = URI.create( Platform.getOS().equals(Platform.OS_WIN32) ? site.getUri().replace('\\', '/') : site.getUri()); IMetadataRepository repository = PDEHelper.safeLoadRepository(uri, monitor); IArtifactRepository artifactRepository = PDEHelper.safeLoadArtifactRepository(uri, monitor); if (repository == null || artifactRepository == null) { if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } return createError("Failed to load update site:" + uri); } List<IInstallableUnit> unitsToInstall = new ArrayList<IInstallableUnit>(); // Query for all entries and then choose required. IQuery<IInstallableUnit> finalQuery = P2Utils.createQuery(site); IQueryResult<IInstallableUnit> result = repository.query(finalQuery, monitor); Set<IInstallableUnit> availableUnits = result.toSet(); if (site.isAllUnits()) { unitsToInstall.addAll(availableUnits); } else { P2Utils.expandFeatures(monitor, repository, availableUnits); Set<String> unitIDs = P2Utils.mapUnitsToId(availableUnits); Set<String> missingUnits = new HashSet<String>(site.getUnits()); missingUnits.removeAll(unitIDs); if (!missingUnits.isEmpty()) { // Some units are not available return createError("Few units are not available:" + Arrays.toString(missingUnits.toArray())); } unitsToInstall.addAll(availableUnits); } if (unitsToInstall.size() > 0) { IInstallableUnit[] unitsAsArray = unitsToInstall .toArray(new IInstallableUnit[unitsToInstall.size()]); URI[] uriArray = new URI[] { uri }; ITargetLocation container = PDEHelper.getTargetService().newIULocation(unitsAsArray, uriArray, IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS); extra.add(container); q7target.addExtra(container); } // Lets mirror all required artifacts into bundle pool, since we don't // really trust P2. IFileArtifactRepository filesRepository = P2TargetUtils.getBundlePool(); List<IInstallableUnit> toInstall = new ArrayList<IInstallableUnit>(); toInstall.addAll(unitsToInstall); P2Utils.installUnits(monitor, artifactRepository, filesRepository, toInstall, 10, null, false, P2Utils.getProvisioningAgent()); MultiStatus rv = new MultiStatus(PLUGIN_ID, 0, "Failed to install next units from repository: " + repository.getName(), null); if (toInstall.size() > 0) { // Not all plugins are installed. for (IInstallableUnit u : toInstall) { rv.add(createError(u.getId())); } return rv; } } catch (CoreException e) { return e.getStatus(); } return Status.OK_STATUS; } public String getIniVMArgs() { List<File> iniFiles = getAppIniFiles(); for (File file : iniFiles) { String vmArgs = readVMArgsFromIniFile(file); if (vmArgs != null) { return vmArgs; } } return null; } private List<File> getAppIniFiles() { List<File> iniFiles = new ArrayList<File>(); if (getInstanceContainer() == null) { return iniFiles; } File installDirectory = new File(getTargetPlatformProfilePath()); if (!installDirectory.exists()) { return iniFiles; } if (Platform.getOS().equals(Platform.OS_MACOSX)) { File[] listFiles = installDirectory.listFiles(); for (File file : listFiles) { if (file.getName().contains(".app")) { installDirectory = new File(file, "/Contents/MacOS"); break; } } } File eclipseIniFile = new File(installDirectory, "eclipse.ini"); //$NON-NLS-1$ if (eclipseIniFile.exists()) { iniFiles.add(eclipseIniFile); return iniFiles; } File[] list = installDirectory.listFiles(); if (list != null) { for (File file : list) { if (file.getName().endsWith(".ini")) { iniFiles.add(file); } } } return iniFiles; } private String readProductFromIniFile(File eclipseIniFile) { BufferedReader in = null; if (eclipseIniFile.exists()) { try { in = new BufferedReader(new FileReader(eclipseIniFile)); String str; while ((str = in.readLine()) != null) { if (str.trim().equals("-product")) { //$NON-NLS-1$ String product = in.readLine(); if (product != null) { return product.trim(); } } } } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } finally { if (in != null) try { in.close(); } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } } } return null; } private String readLauncherLibraryFromIniFile(File eclipseIniFile) { BufferedReader in = null; try { if (eclipseIniFile.exists()) { in = new BufferedReader(new FileReader(eclipseIniFile)); String str; while ((str = in.readLine()) != null) { if (str.trim().equals("--launcher.library")) { //$NON-NLS-1$ String result = in.readLine(); if (result != null) { return result.trim(); } } } } } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } finally { FileUtil.safeClose(in); } return null; } private static final String VMARGS = "-vmargs"; private static final String VM = "-vm"; private List<String> parseIniFile(File eclipseIni) { if (eclipseIni == null || !eclipseIni.exists()) { return emptyList(); } List<String> result = new ArrayList<String>(); try { for (String line : Files.readLines(eclipseIni, UTF_8)) { line = line.trim(); if (line.length() > 0 && line.charAt(0) != '#') { result.add(line); } } } catch (IOException e) { Q7ExtLaunchingPlugin.getDefault().log(e); } return result; } private String getVmArg(File eclipseIniFile) { List<String> lines = parseIniFile(eclipseIniFile); int vmIndex = lines.indexOf("-vm") + 1; return vmIndex == 0 || vmIndex == lines.size() ? null : lines.get(vmIndex); } public String getVmFromIniFile() { for (File file : getAppIniFiles()) { String result = getVmArg(file); if (result != null) { return result; } } return null; } private String readVMArgsFromIniFile(File eclipseIniFile) { if (!eclipseIniFile.exists()) { return null; } List<String> lines = parseIniFile(eclipseIniFile); int vmargsIndex = lines.indexOf(VMARGS); if (vmargsIndex == -1) { return null; } lines = lines.subList(vmargsIndex + 1, lines.size()); int vmIndex = lines.indexOf(VM); if (vmIndex != -1) { lines.subList(vmIndex, Math.min(vmIndex + 2, lines.size())).clear(); } if (lines.isEmpty()) { return null; } return Q7LaunchDelegateUtils.joinCommandArgs(lines); } public String getTemplateConfigLocation() { File iniFile = new File(getTargetPlatformProfilePath(), "configuration/config.ini"); //$NON-NLS-1$ if (!iniFile.exists()) return null; return iniFile.getAbsolutePath(); } public OSArchitecture detectArchitecture(boolean preferCurrentVmArchitecture, StringBuilder detectMsg) { // http://stackoverflow.com/a/808314 final boolean isCurrentVm64 = System.getProperty("os.arch", "not null").contains("64"); boolean has32 = false; boolean has64 = false; String launcher64 = null; String launcher32 = null; List<File> iniFiles = getAppIniFiles(); IPath targetPlatformProfilePath = new Path(getTargetPlatformProfilePath()); Set<String> availableLaunchers = new HashSet<String>(); String os = Platform.getOS(); for (File file : iniFiles) { String launcherLibrary = readLauncherLibraryFromIniFile(file); if (launcherLibrary != null && launcherLibrary.contains(os)) { String configPath = new Path(file.getAbsolutePath()) .removeFirstSegments(targetPlatformProfilePath.segmentCount()).setDevice(null).toOSString(); if (launcherLibrary.contains("x86_64")) { has64 = true; launcher64 = "launcher library\n\t\"" + launcherLibrary + "\" specified in config file: " + configPath; } else if (launcherLibrary.contains("x86") || launcherLibrary.contains("cocoa.macosx")) { has32 = true; launcher32 = "launcher library\n\t\"" + launcherLibrary + "\" specified in config file: " + configPath; } } } if (!has32 && !has64) { TargetBundle[] bundles = target.getAllBundles(); for (TargetBundle b : bundles) { BundleInfo info = b.getBundleInfo(); String name = info.getSymbolicName(); if (name != null && name.startsWith("org.eclipse.equinox.launcher")) { URI location = info.getLocation(); if (location == null || location.getPath() == null) { continue; } String pathString = new Path(info.getLocation().getPath()) .removeFirstSegments(targetPlatformProfilePath.segmentCount()).toOSString(); if (name.contains("x86_64")) { if (name.contains(os)) { has64 = true; launcher64 = "Equinox launcher\n\t- " + pathString; } else { availableLaunchers.add("\t- " + pathString); } } else if (name.contains("x86") || name.contains("cocoa.macosx")) { if (name.contains(os)) { has32 = true; launcher32 = "Equinox launcher\n\t- " + pathString; } else { availableLaunchers.add("\t- " + pathString); } } } } } if (has32 && !has64) { if (detectMsg != null) { detectMsg.append("32bit arch is selected because AUT uses " + launcher32); } return OSArchitecture.x86; } else if (!has32 && has64) { if (detectMsg != null) { detectMsg.append("64bit arch is selected because AUT uses " + launcher64); } return OSArchitecture.x86_64; } else if (preferCurrentVmArchitecture && has32 && has64) { OSArchitecture result = isCurrentVm64 ? OSArchitecture.x86_64 : OSArchitecture.x86; if (detectMsg != null && result.equals(OSArchitecture.x86)) { detectMsg.append( "32bit arch is selected because\n- JVM is 32bit\n- AUT contains both launcher plugins\n\t-" + launcher32 + "\n\t-" + launcher64); } if (detectMsg != null && result.equals(OSArchitecture.x86_64)) { detectMsg.append( "64bit arch is selected because\n- JVM is 64bit\n- AUT contains both launcher plugins\n\t-" + launcher32 + "\n\t-" + launcher64); } return result; } else { if (detectMsg != null) { detectMsg.append("Cannot find appropriate Equinox launcher library.\n"); if (availableLaunchers.size() > 0) { detectMsg.append("Available launchers:\n"); for (String s : availableLaunchers) { detectMsg.append(s).append("\n"); } } } return OSArchitecture.Unknown; } } private Map<String, String> getRunlevelsFromSimpleConfigurator() { Map<String, String> result = new HashMap<String, String>(); if (getTargetPlatformProfilePath() == null) { return result; } File infoFile = new File(getTargetPlatformProfilePath(), SC_BUNDLES_PATH); if (!infoFile.exists()) { return result; } InputStream input = null; try { input = new FileInputStream(infoFile); for (org.eclipse.equinox.internal.simpleconfigurator.utils.BundleInfo bi : (List<org.eclipse.equinox.internal.simpleconfigurator.utils.BundleInfo>) SimpleConfiguratorUtils .readConfiguration(input, infoFile.toURI())) { String name = bi.getSymbolicName(); if (name != null) { result.put(name, String.format("%d:%b", bi.getStartLevel(), bi.isMarkedAsStarted())); } } } catch (Throwable e) { FileUtil.safeClose(input); } return result; } public Map<String, String> getRunlevelsMap() { Map<String, String> result = new HashMap<String, String>(); String osgiBundles = getConfigIniProperty(OSGI_BUNDLES); if (osgiBundles == null) { return result; } if (osgiBundles.contains(SIMPLECONFIGURATOR)) { return getRunlevelsFromSimpleConfigurator(); } // AUT uses bundles specified in osgiBundlesProperty StringTokenizer tokenizer = new StringTokenizer(osgiBundles, ","); //$NON-NLS-1$ while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); int index = token.indexOf('@'); String id = index != -1 ? token.substring(0, index) : token; String tk = token.substring(index + 1); if (tk.indexOf(":") == -1) { tk = tk + ":default"; } result.put(id, tk); } return result; } public String getRuntimeVersion() { if (target != null && target.isResolved()) { String version = ""; Version runtimeBundle = getBundleVersion("org.eclipse.rcptt.tesla.swt"); if (runtimeBundle != null) { version = runtimeBundle.toString(); if (runtimeBundle.getQualifier().equals("qualifier")) { // This is for development version = version + System.currentTimeMillis(); } } return version; } return "unknown"; } private Version getBundleVersion(String name) { if (target != null && target.isResolved()) { ITargetLocation[] containers = target.getTargetLocations(); for (ITargetLocation iBundleContainer : containers) { TargetBundle[] bundles = iBundleContainer.getBundles(); if (bundles != null) { for (TargetBundle iResolvedBundle : bundles) { BundleInfo info = iResolvedBundle.getBundleInfo(); if (Objects.equal(info.getSymbolicName(), name)) { return new Version(info.getVersion()); } } } if (iBundleContainer instanceof IUBundleContainer) { IUBundleContainer ct = (IUBundleContainer) iBundleContainer; try { Field ids = IUBundleContainer.class.getDeclaredField("fIds"); Field versions = IUBundleContainer.class.getDeclaredField("fVersions"); ids.setAccessible(true); versions.setAccessible(true); String[] idsValue = (String[]) ids.get(ct); org.eclipse.equinox.p2.metadata.Version[] versionsValue = (org.eclipse.equinox.p2.metadata.Version[]) versions .get(ct); for (int i = 0; i < idsValue.length; i++) { String n = idsValue[i]; if (n != null && n.equals(name)) { return new Version(versionsValue[i].toString()); } } } catch (Throwable e) { Q7ExtLaunchingPlugin.status("Failed to check runtime version", e); } } } } return null; } public String getEquinoxStartupPath(String packageName) { IPluginModelBase[] targetModels = getTargetModels(); for (IPluginModelBase plugin : targetModels) { if (plugin.getPluginBase().getId().equals(packageName)) { String location = plugin.getInstallLocation(); if (new File(location).isFile()) { return location; } } } return null; } ProfileBundleContainer getInstanceContainer() { final Q7Target target = getQ7Target(); if (target == null) { return null; } final AutInstall install = target.getInstall(); if (install == null) { return null; } return install.container; } public void setBundleContainers(ITargetLocation[] containers) { target.setTargetLocations(containers); initialize(); } @Override public String toString() { return (getName() == null ? "No name" : getName()) + " " + getTargetPlatformProfilePath(); } @Override public Map<String, org.eclipse.equinox.p2.metadata.Version> getVersions() throws CoreException { if (!getStatus().isOK()) throw new CoreException(getStatus()); return AUTInformation.getInformationMap(target); } }