/** * Aptana Studio * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions). * Please see the license.html included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package com.aptana.editor.php.internal.refactoring; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import com.aptana.core.logging.IdeLog; import com.aptana.editor.php.PHPEditorPlugin; import com.aptana.editor.php.indexer.IElementEntry; import com.aptana.editor.php.indexer.IElementsIndex; import com.aptana.editor.php.indexer.PHPGlobalIndexer; import com.aptana.editor.php.internal.builder.BuildPathManager; import com.aptana.editor.php.internal.builder.LocalModule; import com.aptana.editor.php.internal.builder.ProjectBuildPath; import com.aptana.editor.php.internal.builder.WorkspaceFolderBuildpath; import com.aptana.editor.php.internal.core.builder.IBuildPath; import com.aptana.editor.php.internal.core.builder.IModule; import com.aptana.editor.php.internal.indexer.IncludePHPEntryValue; /** * Refactoring utils. * * @author Denis Denisenko */ public final class RefactoringUtils { /** * Constructs include path from one module to another. * * @param from * - module to construct include path from. * @param to * - module to construct include path to. * @return constructed include path */ public static ConstructedIncludePath constructIncludePath(IModule from, IModule to) { IBuildPath fromBuildPath = from.getBuildPath(); IBuildPath toBuildPath = to.getBuildPath(); Set<IBuildPath> fromDependencies = fromBuildPath.getDependencies(); if (fromDependencies.equals(toBuildPath)) { String includePath = constructPathFromRoot(to); return new ConstructedIncludePath(includePath, null, null); } // if "from" build-path directly depends from "to" build-path if (fromDependencies.contains(toBuildPath)) { String includePath = constructPathFromRoot(to); return new ConstructedIncludePath(includePath, null, null); } else { // for local modules using its project-based build-path instead of native module build-path if (to instanceof LocalModule) { IFile file = ((LocalModule) to).getFile(); if (!file.isSynchronized(1)) { try { file.refreshLocal(1, new NullProgressMonitor()); if (file.exists()) { IProject project = file.getProject(); IBuildPath projectBuildPath = BuildPathManager.getInstance() .getBuildPathByResource(project); if (projectBuildPath != null) { IModule alternativeToModule = projectBuildPath.getModule(file); if (alternativeToModule != null) { String includePath = constructPathFromRoot(alternativeToModule); return new ConstructedIncludePath(includePath, fromBuildPath, projectBuildPath); } } } } catch (CoreException e) { IdeLog.logWarning(PHPEditorPlugin.getDefault(), "PHP Refactoring - Error while constructing an include-path (constructIncludePath)", //$NON-NLS-1$ e, PHPEditorPlugin.DEBUG_SCOPE); } } } // in other case, using original build-paths for reporting unsatisfied state String includePath = constructPathFromRoot(to); return new ConstructedIncludePath(includePath, fromBuildPath, toBuildPath); } } /** * Constructs include path from one module to another. * * @param from * - module to construct include path from. * @param toBuildPath * - destination build-path. * @param toPath * - path inside destination build-path. * @return constructed include path */ public static ConstructedIncludePath constructIncludePath(IModule from, IBuildPath toBuildPath, IPath toPath) { IBuildPath fromBuildPath = from.getBuildPath(); Set<IBuildPath> fromDependencies = fromBuildPath.getDependencies(); // if "from" build-path directly depends from "to" build-path if (fromBuildPath.equals(toBuildPath) || fromDependencies.contains(toBuildPath)) { String includePath = constructPathFromRoot(toPath); return new ConstructedIncludePath(includePath, null, null); } else { // for local modules using its project-based build-path instead of native module build-path if (toBuildPath instanceof ProjectBuildPath || toBuildPath instanceof WorkspaceFolderBuildpath) { IProject project = null; if (toBuildPath instanceof ProjectBuildPath) { project = ((ProjectBuildPath) toBuildPath).getProject(); } else { project = ((WorkspaceFolderBuildpath) toBuildPath).getFolder().getProject(); } IBuildPath projectBuildPath = BuildPathManager.getInstance().getBuildPathByResource(project); if (projectBuildPath != null) { String includePath = constructPathFromRoot(toPath); return new ConstructedIncludePath(includePath, fromBuildPath, projectBuildPath); } } // in other case, using original build-paths for reporting unsatisfied state String includePath = constructPathFromRoot(toPath); return new ConstructedIncludePath(includePath, fromBuildPath, toBuildPath); } } /** * Gets all the values of the entries that include the module specified. * * @param index * - index to use. * @param module * - module. * @return map from module to the list of entries defined in that module */ public static Map<IModule, List<IncludePHPEntryValue>> getIncludes(IElementsIndex index, IModule module) { Map<IModule, List<IncludePHPEntryValue>> candidates = new HashMap<IModule, List<IncludePHPEntryValue>>(); String moduleShortName = module.getShortName(); // collecting initial candidates Set<IModule> modules = index.getModules(); for (IModule currentModule : modules) { List<IElementEntry> moduleEntries = index.getModuleEntries(currentModule); for (IElementEntry entry : moduleEntries) { Object entryValue = entry.getValue(); if (entryValue instanceof IncludePHPEntryValue) { IncludePHPEntryValue includeValue = (IncludePHPEntryValue) entryValue; if (includeValue.getIncludePath().endsWith(moduleShortName)) { List<IncludePHPEntryValue> moduleValues = candidates.get(currentModule); if (moduleValues == null) { moduleValues = new ArrayList<IncludePHPEntryValue>(1); candidates.put(currentModule, moduleValues); } moduleValues.add(includeValue); } } } } Map<IModule, List<IncludePHPEntryValue>> result = new HashMap<IModule, List<IncludePHPEntryValue>>(); // filtering candidates for (Entry<IModule, List<IncludePHPEntryValue>> entry : candidates.entrySet()) { IModule currentModule = entry.getKey(); List<IncludePHPEntryValue> values = entry.getValue(); for (IncludePHPEntryValue value : values) { String includePathString = value.getIncludePath(); IPath includePath = new Path(includePathString); IModule resolvedModule = currentModule.getBuildPath().resolveRelativePath(currentModule, includePath); if (resolvedModule != null && resolvedModule.equals(module)) { List<IncludePHPEntryValue> moduleValues = result.get(currentModule); if (moduleValues == null) { moduleValues = new ArrayList<IncludePHPEntryValue>(1); result.put(currentModule, moduleValues); } moduleValues.add(value); } } } return result; } /** * Constructs path from the root of a build path to a module. * * @param module * - module. * @return include path. */ private static String constructPathFromRoot(IModule module) { IPath path = module.getPath(); StringBuilder result = new StringBuilder(); String[] segments = path.segments(); if (segments.length == 0) { return null; } for (int i = 0; i < segments.length - 1; i++) { result.append(segments[i]); result.append('/'); } result.append(segments[segments.length - 1]); return result.toString(); } /** * Constructs path from the root of a build path to a module. * * @param modulePath * - module path from root. * @return include path. */ public static String constructPathFromRoot(IPath modulePath) { StringBuilder result = new StringBuilder(); String[] segments = modulePath.segments(); if (segments.length == 0) { return null; } for (int i = 0; i < segments.length - 1; i++) { result.append(segments[i]); result.append('/'); } result.append(segments[segments.length - 1]); return result.toString(); } /** * Gets module includes. * * @param module * - module * @return module includes list */ public static List<IncludePHPEntryValue> getModuleIncludes(IModule module) { return getModuleIncludes(module, PHPGlobalIndexer.getInstance().getIndex()); } /** * Gets module includes. * * @param module * - module * @param index * - index to use. * @return module includes list */ public static List<IncludePHPEntryValue> getModuleIncludes(IModule module, IElementsIndex index) { List<IncludePHPEntryValue> result = new ArrayList<IncludePHPEntryValue>(); List<IElementEntry> moduleEntries = index.getModuleEntries(module); for (IElementEntry entry : moduleEntries) { Object entryValue = entry.getValue(); if (entryValue instanceof IncludePHPEntryValue) { result.add((IncludePHPEntryValue) entryValue); } } return result; } /** * RefactoringUtils constructor. */ private RefactoringUtils() { } }