package org.eclipse.dltk.tcl.internal.core.packages; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.core.IBuildpathEntry; import org.eclipse.dltk.core.IModelElement; import org.eclipse.dltk.core.IProjectFragment; import org.eclipse.dltk.core.IProjectFragmentTimestamp; import org.eclipse.dltk.core.IScriptFolder; import org.eclipse.dltk.core.ModelException; import org.eclipse.dltk.core.WorkingCopyOwner; import org.eclipse.dltk.internal.core.MementoModelElementUtil; import org.eclipse.dltk.internal.core.ModelElement; import org.eclipse.dltk.internal.core.Openable; import org.eclipse.dltk.internal.core.OpenableElementInfo; import org.eclipse.dltk.internal.core.ScriptProject; import org.eclipse.dltk.internal.core.util.MementoTokenizer; import org.eclipse.dltk.launching.IInterpreterInstall; import org.eclipse.dltk.launching.ScriptRuntime; import org.eclipse.dltk.tcl.core.TclPackagesManager; import org.eclipse.dltk.tcl.core.packages.TclPackageInfo; import org.eclipse.dltk.utils.CorePrinter; public class TclPackageFragment extends Openable implements IProjectFragment, IProjectFragmentTimestamp { public static final IPath PATH = new Path(IBuildpathEntry.BUILDPATH_SPECIAL + "packages#"); private IPath currentPath; private String packageName; protected TclPackageFragment(ScriptProject project, String packageName) { super(project); this.packageName = packageName; /* * package name can contain ':' characters, but they are not allowed in * path, since ':' is used as device separator. */ this.currentPath = PATH.append("@").append( packageName.replace(':', ';')); } public String getElementName() { return "Packages@" + packageName; } /** * @since 2.0 */ public String getPackageName() { return packageName; } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof TclPackageFragment)) return false; TclPackageFragment other = (TclPackageFragment) o; return this.currentPath.equals(other.currentPath) && this.parent.equals(other.parent); } protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws ModelException { IInterpreterInstall install = null; try { install = ScriptRuntime.getInterpreterInstall(getScriptProject()); } catch (CoreException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } return false; } if (install == null) { return false; } List children = new ArrayList(); TclPackageInfo packageInfo = TclPackagesManager.getPackageInfo(install, this.packageName, true); if (packageInfo != null) { children.add(new TclPackageElement(this, this.packageName, packageInfo.getVersion())); info.setChildren((IModelElement[]) children .toArray(new IModelElement[children.size()])); } return true; } public Object createElementInfo() { return new OpenableElementInfo(); } public IModelElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) { switch (token.charAt(0)) { case JEM_SCRIPTFOLDER: if (!memento.hasMoreTokens()) return this; String classFileName = memento.nextToken(); ModelElement classFile = (ModelElement) getScriptFolder(classFileName); return classFile.getHandleFromMemento(memento, owner); case JEM_USER_ELEMENT: return MementoModelElementUtil.getHandleFromMemento(memento, this, owner); } return null; } protected char getHandleMementoDelimiter() { return JEM_USER_ELEMENT; } public void printNode(CorePrinter output) { } public void copy(IPath destination, int updateResourceFlags, int updateModelFlags, IBuildpathEntry sibling, IProgressMonitor monitor) throws ModelException { } public IScriptFolder createScriptFolder(String name, boolean force, IProgressMonitor monitor) throws ModelException { return null; } public void delete(int updateResourceFlags, int updateModelFlags, IProgressMonitor monitor) throws ModelException { } public Object[] getForeignResources() throws ModelException { return new Object[0]; } public int getKind() throws ModelException { return IProjectFragment.K_SOURCE; } public IBuildpathEntry getRawBuildpathEntry() throws ModelException { // return DLTKCore.newSpecialEntry(getPath(), false, true); return null; } public IScriptFolder getScriptFolder(IPath path) { if (path.segmentCount() != 1) { return null; } String name = path.segment(0); return getScriptFolder(name); } public IScriptFolder getScriptFolder(String name) { try { IModelElement[] elements = getChildren(); for (int i = 0; i < elements.length; i++) { if (elements[i].getElementName().equals(name)) { return (IScriptFolder) elements[i]; } } } catch (ModelException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } return null; } public boolean isArchive() { return false; } public boolean isBuiltin() { return false; } public boolean exists() { return true; } public boolean isExternal() { return true; } public void move(IPath destination, int updateResourceFlags, int updateModelFlags, IBuildpathEntry sibling, IProgressMonitor monitor) throws ModelException { } public int getElementType() { return IModelElement.PROJECT_FRAGMENT; } public IPath getPath() { return currentPath; } public IResource getResource() { return null; } public long getTimeStamp() { // Check for package still pressent here or not. Set<String> reqs = new HashSet<String>(); TclPackagesModelProvider.collectRealRequirements(getScriptProject(), reqs); IInterpreterInstall install = TclPackagesModelProvider .resolveInterpreterInstall(getScriptProject()); if (install == null) { return 0; } long fetchTime = TclPackagesManager.getTclInterpreterFetchDate(install); List<TclPackageInfo> infos = TclPackagesManager.getPackageInfos( install, reqs, true); boolean found = false; for (TclPackageInfo packageName : infos) { if (packageName.getName().equals(this.packageName)) { found = true; break; } } if (!found) { return 0; } return currentPath.hashCode() * 17 + fetchTime; } /** * @since 2.0 */ public boolean isBinary() { return false; } /** * @since 2.0 */ @Override public boolean isReadOnly() { return true; } }