package org.eclipse.dltk.tcl.internal.core.sources; 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.core.environment.EnvironmentManager; import org.eclipse.dltk.core.environment.IEnvironment; import org.eclipse.dltk.core.environment.IFileHandle; import org.eclipse.dltk.core.internal.environment.EFSFileHandle; import org.eclipse.dltk.internal.core.MementoModelElementUtil; import org.eclipse.dltk.internal.core.ModelElement; import org.eclipse.dltk.internal.core.ModelElementInfo; 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.TclModuleInfo; import org.eclipse.dltk.tcl.core.packages.TclSourceEntry; import org.eclipse.dltk.tcl.core.packages.UserCorrection; import org.eclipse.dltk.utils.CorePrinter; import org.eclipse.emf.common.util.EList; @SuppressWarnings("restriction") public class TclSourcesFragment extends Openable implements IProjectFragment, IProjectFragmentTimestamp { public static final IPath PATH = new Path(IBuildpathEntry.BUILDPATH_SPECIAL + "sources#"); private IPath currentPath; public TclSourcesFragment(ScriptProject project) { super(project); this.currentPath = PATH.append(project.getElementName()).append("@"); } public String getElementName() { return currentPath.toString(); } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof TclSourcesFragment)) return false; TclSourcesFragment other = (TclSourcesFragment) 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 { List<IModelElement> children = new ArrayList<IModelElement>(1); children.add(new TclSourcesElement(this)); info.setChildren(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 ModelElementInfo.NO_NON_SCRIPT_RESOURCES; } 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 new TclSourcesElement(this, path.toString()); } 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 new TclSourcesElement(this, name); } 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() { // We need to collect all sourced items here. long hash = 0; IEnvironment env = EnvironmentManager.getEnvironment(this); List<TclModuleInfo> modules = TclPackagesManager .getProjectModules(getScriptProject().getElementName()); for (TclModuleInfo tclModuleInfo : modules) { for (TclSourceEntry info : tclModuleInfo.getSourced()) { if (info.getValue() != null) { hash += (hash * 31 + info.getValue().hashCode()) >> 2; } } for (UserCorrection correction : tclModuleInfo .getSourceCorrections()) { if (correction.getOriginalValue() != null) { hash += (hash * 29 + correction.getOriginalValue() .hashCode()) >> 2; } EList<String> uval = correction.getUserValue(); for (String val : uval) { hash += (hash * 29 + val.hashCode()) >> 2; IFileHandle file = env.getFile(new Path(val)); if (file != null) { long lmodif = 0; if (file instanceof EFSFileHandle) { lmodif = ((EFSFileHandle) file).lastModified(); } else { lmodif = file.lastModified(); } hash += lmodif; } } } } return hash; } public boolean containChildrens() { IInterpreterInstall install = null; try { install = ScriptRuntime.getInterpreterInstall(getScriptProject()); } catch (CoreException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } return false; } if (install == null) { return false; } Set<IPath> sources = new HashSet<IPath>(); Set<String> pseudoElements = new HashSet<String>(); TclSourcesUtils.fillSources(install, getScriptProject(), sources, null, pseudoElements); return !sources.isEmpty() || !pseudoElements.isEmpty(); } /** * @since 2.0 */ public boolean isBinary() { return false; } /** * @since 2.0 */ @Override public boolean isReadOnly() { return true; } }