| /******************************************************************************* |
| * Copyright (c) 2005, 2016 IBM Corporation 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 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.internal.core; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Map; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.IBuildpathContainer; |
| import org.eclipse.dltk.core.IBuildpathContainerExtension; |
| import org.eclipse.dltk.core.IBuildpathEntry; |
| import org.eclipse.dltk.core.IBuiltinModuleProvider; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IModelStatusConstants; |
| import org.eclipse.dltk.core.IProjectFragment; |
| import org.eclipse.dltk.core.IScriptFolder; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.ModelException; |
| import org.eclipse.dltk.core.WorkingCopyOwner; |
| import org.eclipse.dltk.internal.core.util.MementoTokenizer; |
| import org.eclipse.dltk.internal.core.util.Util; |
| |
| /** |
| * Project fragment for buildpath script folders and modules. |
| * |
| * @author haiodo |
| * |
| */ |
| public class BuiltinProjectFragment extends ProjectFragment { |
| public final static ArrayList EMPTY_LIST = new ArrayList(); |
| |
| static final Object INTERPRETER_CONTAINER = "org.eclipse.dltk.launching.INTERPRETER_CONTAINER"; //$NON-NLS-1$ |
| |
| protected final IPath fPath; |
| |
| IBuiltinModuleProvider builtinProvider; |
| |
| /** |
| * Maps folder names and source module names. |
| */ |
| |
| protected BuiltinProjectFragment(IPath path, ScriptProject project) { |
| super(null, project); |
| this.fPath = path; |
| builtinProvider = getBuiltinProvider(project); |
| } |
| |
| public static IBuiltinModuleProvider getBuiltinProvider( |
| IScriptProject project) { |
| try { |
| IBuildpathEntry[] entries = project.getRawBuildpath(); |
| IPath containerPath = null; |
| for (int i = 0; i < entries.length; i++) { |
| if (entries[i].getEntryKind() == IBuildpathEntry.BPE_CONTAINER) { |
| IPath path = entries[i].getPath(); |
| if (path.segment(0).equals(INTERPRETER_CONTAINER)) { |
| containerPath = entries[i].getPath(); |
| break; |
| } |
| } |
| } |
| if (containerPath == null) { |
| return null; |
| } |
| IBuildpathContainer buildpathContainer = ModelManager |
| .getModelManager().getBuildpathContainer(containerPath, |
| project); |
| if (buildpathContainer != null |
| && buildpathContainer instanceof IBuildpathContainerExtension) { |
| return ((IBuildpathContainerExtension) buildpathContainer) |
| .getBuiltinProvider(); |
| } |
| } catch (CoreException ex) { |
| if (DLTKCore.DEBUG) { |
| ex.printStackTrace(); |
| } |
| } |
| return null; |
| } |
| |
| public static boolean isSupported(IScriptProject project) { |
| IBuiltinModuleProvider prov = getBuiltinProvider(project); |
| return prov != null && prov.getBuiltinModules() != null; |
| } |
| |
| /** |
| * Compute the package fragment children of this package fragment root. |
| */ |
| @Override |
| protected boolean computeChildren(OpenableElementInfo info, Map newElements) |
| throws ModelException { |
| ArrayList vChildren = new ArrayList(5); |
| ArrayList vForeign = new ArrayList(5); |
| char[][] inclusionPatterns = fullInclusionPatternChars(); |
| char[][] exclusionPatterns = fullExclusionPatternChars(); |
| computeFolderChildren(this.fPath, !Util.isExcluded(this.fPath, |
| inclusionPatterns, exclusionPatterns, true), vChildren, |
| vForeign, newElements, inclusionPatterns, exclusionPatterns); |
| IModelElement[] children = new IModelElement[vChildren.size()]; |
| vChildren.toArray(children); |
| info.setChildren(children); |
| return true; |
| } |
| |
| /** |
| * Starting at this folder, create folders and add them to the collection of |
| * children. |
| * |
| * @param newElements |
| * |
| * @exception ModelException |
| * The resource associated with this project fragment does |
| * not exist |
| */ |
| protected void computeFolderChildren(IPath path, boolean isIncluded, |
| ArrayList vChildren, ArrayList vForeign, Map newElements, |
| char[][] inclusionPatterns, char[][] exclusionPatterns) |
| throws ModelException { |
| BuiltinScriptFolder fldr = (BuiltinScriptFolder) getScriptFolder(Path.EMPTY); |
| vChildren.add(fldr); |
| if (this.builtinProvider == null) { |
| return; |
| } |
| try { |
| BuiltinScriptFolderInfo fragInfo = new BuiltinScriptFolderInfo(); |
| fldr.computeChildren(fragInfo, |
| this.builtinProvider.getBuiltinModules()); |
| fldr.computeForeignResources(fragInfo); |
| newElements.put(fldr, fragInfo); |
| } catch (IllegalArgumentException e) { |
| throw new ModelException(e, |
| IModelStatusConstants.ELEMENT_DOES_NOT_EXIST); |
| /* |
| * could be thrown by ElementTree when path is not found |
| */ |
| } |
| } |
| |
| @Override |
| public IScriptFolder getScriptFolder(IPath path) { |
| try { |
| String portablePath = path.toPortableString(); |
| IModelElement[] children = getChildren(); |
| for (int i = 0; i < children.length; ++i) { |
| IModelElement child = children[i]; |
| if (child.getElementType() == SCRIPT_FOLDER |
| && ((IScriptFolder) child).getElementName().equals( |
| portablePath)) { |
| return ((IScriptFolder) child); |
| } |
| } |
| } catch (ModelException e) { |
| if (DLTKCore.DEBUG) { |
| e.printStackTrace(); |
| } |
| } |
| return new BuiltinScriptFolder(this, path); |
| } |
| |
| @Override |
| public IScriptFolder getScriptFolder(String path) { |
| return getScriptFolder(new Path(path)); |
| } |
| |
| @Override |
| public boolean isReadOnly() { |
| return true; |
| } |
| |
| @Override |
| protected Object createElementInfo() { |
| return new BuiltinProjectFragmentInfo(); |
| } |
| |
| @Override |
| public boolean isArchive() { |
| return false; |
| } |
| |
| @Override |
| public boolean isExternal() { |
| return true; |
| } |
| |
| @Override |
| public boolean isBuiltin() { |
| return true; |
| } |
| |
| @Override |
| public IResource getUnderlyingResource() throws ModelException { |
| return null; |
| } |
| |
| @Override |
| public int hashCode() { |
| return this.fPath.hashCode(); |
| } |
| |
| @Override |
| public IPath getPath() { |
| if (isExternal()) { |
| return this.fPath; |
| } else { |
| return super.getPath(); |
| } |
| } |
| |
| @Override |
| public IResource getResource() { |
| return null; |
| } |
| |
| /** |
| * Returns whether the corresponding resource or associated file exists |
| */ |
| @Override |
| protected boolean resourceExists() { |
| return true; |
| } |
| |
| @Override |
| protected void toStringAncestors(StringBuffer buffer) { |
| if (isExternal()) |
| return; |
| super.toStringAncestors(buffer); |
| } |
| |
| @Override |
| public int getKind() { |
| return IProjectFragment.K_SOURCE; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) |
| return true; |
| if (o instanceof BuiltinProjectFragment) { |
| BuiltinProjectFragment other = (BuiltinProjectFragment) o; |
| return this.fPath.equals(other.fPath); |
| } |
| return false; |
| } |
| |
| @Override |
| public String getElementName() { |
| return fPath.toOSString().replace(File.separatorChar, |
| JEM_SKIP_DELIMETER); |
| } |
| |
| @Override |
| public void getHandleMemento(StringBuffer buff) { |
| ((ModelElement) getParent()).getHandleMemento(buff); |
| buff.append(getHandleMementoDelimiter()); |
| escapeMementoName(buff, getElementName()); |
| } |
| |
| @Override |
| public IModelElement getHandleFromMemento(String token, |
| MementoTokenizer memento, WorkingCopyOwner owner) { |
| switch (token.charAt(0)) { |
| case JEM_SCRIPTFOLDER: |
| String pkgName; |
| if (memento.hasMoreTokens()) { |
| pkgName = memento.nextToken(); |
| char firstChar = pkgName.charAt(0); |
| if (firstChar == JEM_SOURCEMODULE || firstChar == JEM_COUNT) { |
| token = pkgName; |
| pkgName = IProjectFragment.DEFAULT_SCRIPT_FOLDER_NAME; |
| } else { |
| token = null; |
| } |
| } else { |
| pkgName = IScriptFolder.DEFAULT_FOLDER_NAME; |
| token = null; |
| } |
| ModelElement pkg = (ModelElement) getScriptFolder(pkgName); |
| if (token == null) { |
| return pkg.getHandleFromMemento(memento, owner); |
| } else { |
| return pkg.getHandleFromMemento(token, memento, owner); |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| protected char getHandleMementoDelimiter() { |
| return JEM_PROJECTFRAGMENT; |
| } |
| |
| @Override |
| public IBuildpathEntry getRawBuildpathEntry() throws ModelException { |
| IBuildpathEntry rawEntry = null; |
| ScriptProject project = (ScriptProject) this.getScriptProject(); |
| project.getResolvedBuildpath(); // force the reverse rawEntry cache to |
| // be populated |
| Map<IPath, IBuildpathEntry> rootPathToRawEntries = project |
| .getPerProjectInfo().rootPathToRawEntries; |
| if (rootPathToRawEntries != null) { |
| rawEntry = rootPathToRawEntries.get(this.getPath()); |
| } |
| if (rawEntry == null) { |
| throw new ModelException(new ModelStatus( |
| IModelStatusConstants.ELEMENT_NOT_ON_BUILDPATH, this)); |
| } |
| return rawEntry; |
| } |
| |
| @Override |
| public IBuildpathEntry getBuildpathEntry() throws ModelException { |
| ScriptProject project = (ScriptProject) this.getScriptProject(); |
| IBuildpathEntry rawEntry = getRawBuildpathEntry(); |
| // try to guest map from internal element. |
| if (rawEntry != null |
| && rawEntry.getEntryKind() == IBuildpathEntry.BPE_CONTAINER) { |
| IBuildpathContainer container = DLTKCore.getBuildpathContainer( |
| rawEntry.getPath(), project); |
| IBuildpathEntry entrys[] = container.getBuildpathEntries(); |
| for (int i = 0; i < entrys.length; ++i) { |
| if (entrys[i].getPath().equals( |
| new Path(this.getPath().segment(0)))) { |
| return entrys[i]; |
| } |
| } |
| } |
| return rawEntry; |
| } |
| |
| /* |
| * Validate whether this project fragment is on the buildpath of its |
| * project. |
| */ |
| @Override |
| protected IStatus validateOnBuildpath() { |
| return Status.OK_STATUS; |
| } |
| |
| @Override |
| public boolean exists() { |
| return true; |
| } |
| |
| public long lastModified() { |
| return builtinProvider != null ? builtinProvider.lastModified() : 0; |
| } |
| } |