/******************************************************************************* * Copyright (c) 2017 Alex Xu 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: * Alex Xu - initial API and implementation *******************************************************************************/ package org.eclipse.php.internal.server.core.builtin; import java.io.File; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.php.internal.debug.core.PHPExeUtil; import org.eclipse.php.internal.debug.core.PHPExeUtil.PHPModuleInfo; import org.eclipse.php.internal.debug.core.debugger.AbstractDebuggerConfiguration; import org.eclipse.php.internal.debug.core.preferences.PHPDebuggersRegistry; import org.eclipse.php.internal.debug.core.preferences.PHPexeItem; import org.eclipse.php.internal.debug.core.preferences.PHPexes; import org.eclipse.wst.server.core.IRuntimeType; import org.eclipse.wst.server.core.IRuntimeWorkingCopy; import org.eclipse.wst.server.core.ServerCore; import org.eclipse.wst.server.core.model.RuntimeLocatorDelegate; @SuppressWarnings("restriction") public class PHPRuntimeLocator extends RuntimeLocatorDelegate { private static final String[] PHP_CANDIDATE_BIN = { "php", "php-cli", //$NON-NLS-1$ //$NON-NLS-2$ "php-cgi", "php.exe", "php-cli.exe", "php-cgi.exe" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ protected static final String[] runtimeTypes = new String[] { "org.eclipse.php.server.runtime.54", //$NON-NLS-1$ "org.eclipse.php.server.runtime.55", "org.eclipse.php.server.runtime.56", //$NON-NLS-1$ //$NON-NLS-2$ "org.eclipse.php.server.runtime.70", "org.eclipse.php.server.runtime.71" }; //$NON-NLS-1$ //$NON-NLS-2$ /* * (non-Javadoc) * * @see org.eclipse.wst.server.core.model.IRuntimeFactoryDelegate# * getKnownRuntimes() */ @Override public void searchForRuntimes(IPath path, IRuntimeSearchListener listener, IProgressMonitor monitor) { final List<File> locations = new ArrayList<File>(); final List<PHPexeItem> found = new ArrayList<PHPexeItem>(); searchForRuntimes2(path.toFile(), locations, monitor); if (!locations.isEmpty()) { monitor.setTaskName(Messages.PHPRuntimeLocator_Processing_search_results); Iterator<File> iter2 = locations.iterator(); while (iter2.hasNext()) { if (monitor.isCanceled()) break; File location = iter2.next(); PHPexeItem phpExe = new PHPexeItem(null, location, null, null, true); if (phpExe.getName() == null) continue; String nameCopy = new String(phpExe.getName()); monitor.subTask(MessageFormat.format(Messages.PHPRuntimeLocator_Fetching_php_exe_info, nameCopy)); List<PHPModuleInfo> modules = PHPExeUtil.getModules(phpExe); AbstractDebuggerConfiguration[] debuggers = PHPDebuggersRegistry.getDebuggersConfigurations(); for (AbstractDebuggerConfiguration debugger : debuggers) { for (PHPModuleInfo m : modules) if (m.getName().equalsIgnoreCase(debugger.getModuleId())) { phpExe.setDebuggerID(debugger.getDebuggerId()); break; } } if (phpExe.getDebuggerID() == null) phpExe.setDebuggerID(PHPDebuggersRegistry.NONE_DEBUGGER_ID); phpExe.setName(nameCopy); phpExe.setLoadDefaultINI(true); if (phpExe.getExecutable() != null) { found.add(phpExe); } } } for (PHPexeItem phpExe : found) { IRuntimeWorkingCopy runtime = getRuntimeFromDir(phpExe, monitor); if (runtime != null) { PHPexes.getInstance().addItem(phpExe); listener.runtimeFound(runtime); } } } /** * Searches the specified directory recursively for installed PHP * executables, adding each detected executable to the <code>found</code> * list. Any directories specified in the <code>ignore</code> are not * traversed. * * @param directory * @param found * @param types * @param ignore */ protected void searchForRuntimes2(final File directory, final List<File> found, final IProgressMonitor monitor) { if (monitor.isCanceled()) return; // Search the root directory List<File> foundExecs = findPHPExecutable(directory); if (!foundExecs.isEmpty()) { found.addAll(foundExecs); monitor.setTaskName(MessageFormat.format(Messages.PHPRuntimeLocator_Searching_with_found, found.size())); } final String[] names = directory.list(); if (names == null) return; final List<File> subDirs = new ArrayList<File>(); for (String element : names) { if (monitor.isCanceled()) return; final File file = new File(directory, element); if (file.isDirectory()) { try { monitor.subTask(MessageFormat.format(Messages.PHPRuntimeLocator_14, file.getCanonicalPath())); } catch (final IOException e) { } if (monitor.isCanceled()) return; subDirs.add(file); } } while (!subDirs.isEmpty()) { final File subDir = subDirs.remove(0); searchForRuntimes2(subDir, found, monitor); if (monitor.isCanceled()) return; } } /** * Locate a PHP executable file in the PHP location given to this method. * The location should be a directory. The search is done for php and * php.exe only. * * @param phpLocation * A directory that might hold a PHP executable. * @return A PHP executable file. */ private static List<File> findPHPExecutable(File phpLocation) { List<File> found = new ArrayList<File>(0); for (String element : PHP_CANDIDATE_BIN) { File phpExecFile = new File(phpLocation, element); if (phpExecFile.exists() && !phpExecFile.isDirectory()) { found.add(phpExecFile); } } return found; } protected static IRuntimeWorkingCopy getRuntimeFromDir(PHPexeItem phpExe, IProgressMonitor monitor) { for (int i = 0; i < runtimeTypes.length; i++) { try { IRuntimeType runtimeType = ServerCore.findRuntimeType(runtimeTypes[i]); String absolutePath = phpExe.getExecutable().getParent(); String id = absolutePath.replace(File.separatorChar, '_').replace(':', '-'); IRuntimeWorkingCopy runtime = runtimeType.createRuntime(id, monitor); runtime.setName(phpExe.getName()); runtime.setLocation(new Path(absolutePath)); PHPRuntime phpRuntime = (PHPRuntime) runtime.loadAdapter(PHPRuntime.class, monitor); if (phpRuntime != null) phpRuntime.setExecutableInstall(phpExe); IStatus status = runtime.validate(monitor); if (status == null || status.getSeverity() != IStatus.ERROR) return runtime; Trace.trace(Trace.FINER, "False runtime found at " + absolutePath + ": " + status.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ } catch (Exception e) { Trace.trace(Trace.SEVERE, "Could not find runtime", e); //$NON-NLS-1$ } } return null; } }