/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.core; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.Map; import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IJavaModel; import net.sourceforge.phpdt.core.IJavaProject; import net.sourceforge.phpdt.core.IOpenable; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.core.WorkingCopyOwner; import net.sourceforge.phpdt.internal.core.util.MementoTokenizer; import net.sourceforge.phpdt.internal.core.util.Util; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; //incastrix //import org.eclipse.jface.text.Assert; import org.eclipse.core.runtime.Assert; /** * Implementation of IJavaModel. The Java Model maintains a cache of * active IJavaProjects in a workspace. A Java Model is specific to a * workspace. To retrieve a workspace's model, use the * #getJavaModel(IWorkspace) method. * * @see IJavaModel */ public class JavaModel extends Openable implements IJavaModel { /** * A set of java.io.Files used as a cache of external jars that are known to * be existing. Note this cache is kept for the whole session. */ public static HashSet existingExternalFiles = new HashSet(); /** * Constructs a new Java Model on the given workspace. Note that only one * instance of JavaModel handle should ever be created. One should only * indirect through JavaModelManager#getJavaModel() to get access to it. * * @exception Error * if called more than once */ protected JavaModel() throws Error { super(null, "" /* workspace has empty name */); //$NON-NLS-1$ } protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) /* * throws * JavaModelException */{ // determine my children IProject[] projects = ResourcesPlugin.getWorkspace().getRoot() .getProjects(); for (int i = 0, max = projects.length; i < max; i++) { IProject project = projects[i]; if (JavaProject.hasJavaNature(project)) { info.addChild(getJavaProject(project)); } } newElements.put(this, info); return true; } /* * @see IJavaModel */ public boolean contains(IResource resource) { switch (resource.getType()) { case IResource.ROOT: case IResource.PROJECT: return true; } // file or folder IJavaProject[] projects; try { projects = this.getJavaProjects(); } catch (JavaModelException e) { return false; } for (int i = 0, length = projects.length; i < length; i++) { JavaProject project = (JavaProject) projects[i]; if (!project.contains(resource)) { return false; } } return true; } /** * @see IJavaModel */ public void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { runOperation(new CopyResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); } else { runOperation( new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); } } /** * Returns a new element info for this element. */ protected Object createElementInfo() { return new JavaModelInfo(); } /** * @see IJavaModel */ public void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException { if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { runOperation(new DeleteResourceElementsOperation(elements, force), monitor); } else { runOperation(new DeleteElementsOperation(elements, force), monitor); } } /** * Finds the given project in the list of the java model's children. Returns * null if not found. */ public IJavaProject findJavaProject(IProject project) { try { IJavaProject[] projects = this.getOldJavaProjectsList(); for (int i = 0, length = projects.length; i < length; i++) { IJavaProject javaProject = projects[i]; if (project.equals(javaProject.getProject())) { return javaProject; } } } catch (JavaModelException e) { } return null; } /** * @see IJavaElement */ public int getElementType() { return JAVA_MODEL; } /** * Flushes the cache of external files known to be existing. */ public static void flushExternalFileCache() { existingExternalFiles = new HashSet(); } /** */ // protected boolean generateInfos(OpenableElementInfo info, // IProgressMonitor pm, Map newElements, IResource underlyingResource) // throws JavaModelException { // // JavaModelManager.getJavaModelManager().putInfo(this, info); // // determine my children // IProject[] projects = ResourcesPlugin.getWorkspace().getRoot() // .getProjects(); // for (int i = 0, max = projects.length; i < max; i++) { // IProject project = projects[i]; // if (JavaProject.hasJavaNature(project)) { // info.addChild(getJavaProject(project)); // } // } // return true; // } /** * Returns the IJavaElement represented by the * String memento. * * @see getHandleMemento() */ // protected IJavaElement getHandleFromMementoForBinaryMembers(String // memento, IPackageFragmentRoot root, int rootEnd, int end) throws // JavaModelException { // // //deal with class file and binary members // IPackageFragment frag = null; // if (rootEnd == end - 1) { // //default package // frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME); // } else { // frag= root.getPackageFragment(memento.substring(rootEnd + 1, end)); // } // int oldEnd = end; // end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd); // if (end == -1) { // //we ended with a class file // return frag.getClassFile(memento.substring(oldEnd + 1)); // } // IClassFile cf = frag.getClassFile(memento.substring(oldEnd + 1, end)); // oldEnd = end; // end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd); // oldEnd = end; // end = memento.indexOf(JavaElement.JEM_FIELD, end); // if (end != -1) { // //binary field // IType type = cf.getType(); // return type.getField(memento.substring(end + 1)); // } // end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd); // if (end != -1) { // //binary method // oldEnd = end; // IType type = cf.getType(); // String methodName; // end = memento.lastIndexOf(JavaElement.JEM_METHOD); // String[] parameterTypes = null; // if (end == oldEnd) { // methodName = memento.substring(end + 1); // //no parameter types // parameterTypes = new String[] {}; // } else { // String parameters = memento.substring(oldEnd + 1); // StringTokenizer tokenizer = new StringTokenizer(parameters, new // String(new char[] {JavaElement.JEM_METHOD})); // parameterTypes = new String[tokenizer.countTokens() - 1]; // methodName= tokenizer.nextToken(); // int i = 0; // while (tokenizer.hasMoreTokens()) { // parameterTypes[i] = tokenizer.nextToken(); // i++; // } // } // return type.getMethod(methodName, parameterTypes); // } // // //binary type // return cf.getType(); // } /** * Returns the IPackageFragmentRoot represented by the * String memento. * * @see getHandleMemento() */ // protected IPackageFragmentRoot getHandleFromMementoForRoot(String // memento, JavaProject project, int projectEnd, int rootEnd) { // String rootName = null; // if (rootEnd == projectEnd - 1) { // //default root // rootName = IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH; // } else { // rootName = memento.substring(projectEnd + 1, rootEnd); // } // return project.getPackageFragmentRoot(new Path(rootName)); // } /** * Returns the IJavaElement represented by the * String memento. * * @see getHandleMemento() */ // protected IJavaElement getHandleFromMementoForSourceMembers(String // memento, IPackageFragmentRoot root, int rootEnd, int end) throws // JavaModelException { // // //deal with compilation units and source members // IPackageFragment frag = null; // if (rootEnd == end - 1) { // //default package // frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME); // } else { // frag= root.getPackageFragment(memento.substring(rootEnd + 1, end)); // } // int oldEnd = end; // end = memento.indexOf(JavaElement.JEM_PACKAGEDECLARATION, end); // if (end != -1) { // //package declaration // ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + // 1, end)); // return cu.getPackageDeclaration(memento.substring(end + 1)); // } // end = memento.indexOf(JavaElement.JEM_IMPORTDECLARATION, oldEnd); // if (end != -1) { // //import declaration // ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + // 1, end)); // return cu.getImport(memento.substring(end + 1)); // } // int typeStart = memento.indexOf(JavaElement.JEM_TYPE, oldEnd); // if (typeStart == -1) { // //we ended with a compilation unit // return frag.getCompilationUnit(memento.substring(oldEnd + 1)); // } // // //source members // ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + // 1, typeStart)); // end = memento.indexOf(JavaElement.JEM_FIELD, oldEnd); // if (end != -1) { // //source field // IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, // end); // return type.getField(memento.substring(end + 1)); // } // end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd); // if (end != -1) { // //source method // IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, // end); // oldEnd = end; // String methodName; // end = memento.lastIndexOf(JavaElement.JEM_METHOD); // String[] parameterTypes = null; // if (end == oldEnd) { // methodName = memento.substring(end + 1); // //no parameter types // parameterTypes = new String[] {}; // } else { // String parameters = memento.substring(oldEnd + 1); // StringTokenizer mTokenizer = new StringTokenizer(parameters, new // String(new char[] {JavaElement.JEM_METHOD})); // parameterTypes = new String[mTokenizer.countTokens() - 1]; // methodName = mTokenizer.nextToken(); // int i = 0; // while (mTokenizer.hasMoreTokens()) { // parameterTypes[i] = mTokenizer.nextToken(); // i++; // } // } // return type.getMethod(methodName, parameterTypes); // } // // end = memento.indexOf(JavaElement.JEM_INITIALIZER, oldEnd); // if (end != -1 ) { // //initializer // IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, // end); // return type.getInitializer(Integer.parseInt(memento.substring(end + 1))); // } // //source type // return getHandleFromMementoForSourceType(memento, cu, typeStart, // memento.length()); // } /** * Returns the IJavaElement represented by the * String memento. * * @see getHandleMemento() */ // protected IType getHandleFromMementoForSourceType(String memento, // ICompilationUnit cu, int typeStart, int typeEnd) throws // JavaModelException { // int end = memento.lastIndexOf(JavaElement.JEM_TYPE); // IType type = null; // if (end == typeStart) { // String typeName = memento.substring(typeStart + 1, typeEnd); // type = cu.getType(typeName); // // } else { // String typeNames = memento.substring(typeStart + 1, typeEnd); // StringTokenizer tokenizer = new StringTokenizer(typeNames, new String(new // char[] {JavaElement.JEM_TYPE})); // type = cu.getType(tokenizer.nextToken()); // while (tokenizer.hasMoreTokens()) { // //deal with inner types // type= type.getType(tokenizer.nextToken()); // } // } // return type; // } /* * @see JavaElement */ public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) { switch (token.charAt(0)) { case JEM_COUNT: return getHandleUpdatingCountFromMemento(memento, owner); case JEM_JAVAPROJECT: String projectName = memento.nextToken(); JavaElement project = (JavaElement) getJavaProject(projectName); return project.getHandleFromMemento(memento, owner); } return null; } /** * @see JavaElement#getHandleMemento() */ public String getHandleMemento() { return getElementName(); } /** * Returns the char that marks the start of this handles * contribution to a memento. */ protected char getHandleMementoDelimiter() { Assert.isTrue(false, "Should not be called"); //$NON-NLS-1$ return 0; } /** * @see IJavaModel */ public IJavaProject getJavaProject(String name) { return new JavaProject(ResourcesPlugin.getWorkspace().getRoot() .getProject(name), this); } /** * Returns the active Java project associated with the specified resource, * or null if no Java project yet exists for the resource. * * @exception IllegalArgumentException * if the given resource is not one of an IProject, IFolder, * or IFile. */ public IJavaProject getJavaProject(IResource resource) { switch (resource.getType()) { case IResource.FOLDER: return new JavaProject(((IFolder) resource).getProject(), this); case IResource.FILE: return new JavaProject(((IFile) resource).getProject(), this); case IResource.PROJECT: return new JavaProject((IProject) resource, this); default: throw new IllegalArgumentException(Util .bind("element.invalidResourceForProject")); //$NON-NLS-1$ } } /** * @see IJavaModel */ public IJavaProject[] getJavaProjects() throws JavaModelException { ArrayList list = getChildrenOfType(JAVA_PROJECT); IJavaProject[] array = new IJavaProject[list.size()]; list.toArray(array); return array; } // /** // * @see IJavaModel // */ // public Object[] getNonJavaResources() throws JavaModelException { // return ((JavaModelInfo) getElementInfo()).getNonJavaResources(); // } /** * Workaround for bug 15168 circular errors not reported Returns the list of * java projects before resource delta processing has started. */ public IJavaProject[] getOldJavaProjectsList() throws JavaModelException { JavaModelManager manager = JavaModelManager.getJavaModelManager(); return manager.javaProjectsCache == null ? this.getJavaProjects() : manager.javaProjectsCache; } /* * @see IJavaElement */ public IPath getPath() { return Path.ROOT; } /* * @see IJavaElement */ public IResource getResource() { return ResourcesPlugin.getWorkspace().getRoot(); } /** * @see IOpenable */ public IResource getUnderlyingResource() throws JavaModelException { return null; } /** * Returns the workbench associated with this object. */ public IWorkspace getWorkspace() { return ResourcesPlugin.getWorkspace(); } /** * @see IJavaModel */ public void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { runOperation(new MoveResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); } else { runOperation( new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor); } } /** * @see IJavaModel#refreshExternalArchives(IJavaElement[], IProgressMonitor) */ // public void refreshExternalArchives(IJavaElement[] elementsScope, // IProgressMonitor monitor) throws JavaModelException { // if (elementsScope == null){ // elementsScope = new IJavaElement[] { this }; // } // JavaModelManager.getJavaModelManager().deltaProcessor.checkExternalArchiveChanges(elementsScope, // monitor); // } /** * @see IJavaModel */ public void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException { MultiOperation op; if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) { op = new RenameResourceElementsOperation(elements, destinations, renamings, force); } else { op = new RenameElementsOperation(elements, destinations, renamings, force); } runOperation(op, monitor); } /* * @see JavaElement#rootedAt(IJavaProject) */ public IJavaElement rootedAt(IJavaProject project) { return this; } /** * Configures and runs the MultiOperation. */ protected void runOperation(MultiOperation op, IJavaElement[] elements, IJavaElement[] siblings, String[] renamings, IProgressMonitor monitor) throws JavaModelException { op.setRenamings(renamings); if (siblings != null) { for (int i = 0; i < elements.length; i++) { op.setInsertBefore(elements[i], siblings[i]); } } // runOperation(op, monitor); op.runOperation(monitor); } /** * @private Debugging purposes */ protected void toStringInfo(int tab, StringBuffer buffer, Object info) { buffer.append(this.tabString(tab)); buffer.append("Java Model"); //$NON-NLS-1$ if (info == null) { buffer.append(" (not open)"); //$NON-NLS-1$ } } /** * Helper method - returns the targeted item (IResource if internal or * java.io.File if external), or null if unbound Internal items must be * referred to using container relative paths. */ public static Object getTarget(IContainer container, IPath path, boolean checkResourceExistence) { if (path == null) return null; // lookup - inside the container if (path.getDevice() == null) { // container relative paths should not // contain a device // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=18684) // (case of a workspace rooted at d:\ ) IResource resource = container.findMember(path); if (resource != null) { if (!checkResourceExistence || resource.exists()) return resource; return null; } } // if path is relative, it cannot be an external path // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517) if (!path.isAbsolute()) return null; // lookup - outside the container File externalFile = new File(path.toOSString()); if (!checkResourceExistence) { return externalFile; } else if (existingExternalFiles.contains(externalFile)) { return externalFile; } else { if (JavaModelManager.ZIP_ACCESS_VERBOSE) { System.out .println("(" + Thread.currentThread() + ") [JavaModel.getTarget(...)] Checking existence of " + path.toString()); //$NON-NLS-1$ //$NON-NLS-2$ } if (externalFile.exists()) { // cache external file existingExternalFiles.add(externalFile); return externalFile; } } return null; } }