1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
13 import java.util.ArrayList;
14 import java.util.HashSet;
16 import net.sourceforge.phpdt.core.IJavaElement;
17 import net.sourceforge.phpdt.core.IJavaModel;
18 import net.sourceforge.phpdt.core.IJavaProject;
19 import net.sourceforge.phpdt.core.JavaModelException;
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.resources.IFolder;
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.resources.IWorkspace;
26 import org.eclipse.core.resources.ResourcesPlugin;
27 import org.eclipse.core.runtime.IPath;
28 import org.eclipse.core.runtime.Path;
29 import org.eclipse.jface.util.Assert;
33 * Implementation of <code>IJavaModel<code>. The Java Model maintains a cache of
34 * active <code>IJavaProject</code>s in a workspace. A Java Model is specific to a
35 * workspace. To retrieve a workspace's model, use the
36 * <code>#getJavaModel(IWorkspace)</code> method.
40 public class JavaModel extends Openable implements IJavaModel {
43 * A set of java.io.Files used as a cache of external jars that
44 * are known to be existing.
45 * Note this cache is kept for the whole session.
47 public static HashSet existingExternalFiles = new HashSet();
50 * Constructs a new Java Model on the given workspace.
51 * Note that only one instance of JavaModel handle should ever be created.
52 * One should only indirect through JavaModelManager#getJavaModel() to get
55 * @exception Error if called more than once
57 protected JavaModel() throws Error {
58 super(JAVA_MODEL, null, "" /*workspace has empty name*/); //$NON-NLS-1$
63 //public boolean contains(IResource resource) {
64 // switch (resource.getType()) {
65 // case IResource.ROOT:
66 // case IResource.PROJECT:
70 // IJavaProject[] projects;
72 // projects = this.getJavaProjects();
73 // } catch (JavaModelException e) {
76 // for (int i = 0, length = projects.length; i < length; i++) {
77 // JavaProject project = (JavaProject)projects[i];
79 // if (!project.contains(resource)) {
88 //public void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
89 // if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
90 // runOperation(new CopyResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
92 // runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
96 * Returns a new element info for this element.
98 //protected OpenableElementInfo createElementInfo() {
99 // return new JavaModelInfo();
105 //public void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException {
106 // if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
107 // runOperation(new DeleteResourceElementsOperation(elements, force), monitor);
109 // runOperation(new DeleteElementsOperation(elements, force), monitor);
113 * Finds the given project in the list of the java model's children.
114 * Returns null if not found.
116 public IJavaProject findJavaProject(IProject project) {
118 IJavaProject[] projects = this.getOldJavaProjectsList();
119 for (int i = 0, length = projects.length; i < length; i++) {
120 IJavaProject javaProject = projects[i];
121 if (project.equals(javaProject.getProject())) {
125 } catch (JavaModelException e) {
131 * Flushes the cache of external files known to be existing.
133 public static void flushExternalFileCache() {
134 existingExternalFiles = new HashSet();
139 //protected boolean generateInfos(
140 // OpenableElementInfo info,
141 // IProgressMonitor pm,
143 // IResource underlyingResource) throws JavaModelException {
145 // JavaModelManager.getJavaModelManager().putInfo(this, info);
146 // // determine my children
147 // IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
148 // for (int i = 0, max = projects.length; i < max; i++) {
149 // IProject project = projects[i];
150 // if (JavaProject.hasJavaNature(project)) {
151 // info.addChild(getJavaProject(project));
157 * Returns the <code>IJavaElement</code> represented by the <code>String</code>
159 * @see getHandleMemento()
161 //protected IJavaElement getHandleFromMementoForBinaryMembers(String memento, IPackageFragmentRoot root, int rootEnd, int end) throws JavaModelException {
163 // //deal with class file and binary members
164 // IPackageFragment frag = null;
165 // if (rootEnd == end - 1) {
167 // frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
169 // frag= root.getPackageFragment(memento.substring(rootEnd + 1, end));
172 // end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
174 // //we ended with a class file
175 // return frag.getClassFile(memento.substring(oldEnd + 1));
177 // IClassFile cf = frag.getClassFile(memento.substring(oldEnd + 1, end));
179 // end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
181 // end = memento.indexOf(JavaElement.JEM_FIELD, end);
184 // IType type = cf.getType();
185 // return type.getField(memento.substring(end + 1));
187 // end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd);
191 // IType type = cf.getType();
192 // String methodName;
193 // end = memento.lastIndexOf(JavaElement.JEM_METHOD);
194 // String[] parameterTypes = null;
195 // if (end == oldEnd) {
196 // methodName = memento.substring(end + 1);
197 // //no parameter types
198 // parameterTypes = new String[] {};
200 // String parameters = memento.substring(oldEnd + 1);
201 // StringTokenizer tokenizer = new StringTokenizer(parameters, new String(new char[] {JavaElement.JEM_METHOD}));
202 // parameterTypes = new String[tokenizer.countTokens() - 1];
203 // methodName= tokenizer.nextToken();
205 // while (tokenizer.hasMoreTokens()) {
206 // parameterTypes[i] = tokenizer.nextToken();
210 // return type.getMethod(methodName, parameterTypes);
214 // return cf.getType();
217 * Returns the <code>IPackageFragmentRoot</code> represented by the <code>String</code>
219 * @see getHandleMemento()
221 //protected IPackageFragmentRoot getHandleFromMementoForRoot(String memento, JavaProject project, int projectEnd, int rootEnd) {
222 // String rootName = null;
223 // if (rootEnd == projectEnd - 1) {
225 // rootName = IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH;
227 // rootName = memento.substring(projectEnd + 1, rootEnd);
229 // return project.getPackageFragmentRoot(new Path(rootName));
232 * Returns the <code>IJavaElement</code> represented by the <code>String</code>
234 * @see getHandleMemento()
236 //protected IJavaElement getHandleFromMementoForSourceMembers(String memento, IPackageFragmentRoot root, int rootEnd, int end) throws JavaModelException {
238 // //deal with compilation units and source members
239 // IPackageFragment frag = null;
240 // if (rootEnd == end - 1) {
242 // frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
244 // frag= root.getPackageFragment(memento.substring(rootEnd + 1, end));
247 // end = memento.indexOf(JavaElement.JEM_PACKAGEDECLARATION, end);
249 // //package declaration
250 // ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, end));
251 // return cu.getPackageDeclaration(memento.substring(end + 1));
253 // end = memento.indexOf(JavaElement.JEM_IMPORTDECLARATION, oldEnd);
255 // //import declaration
256 // ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, end));
257 // return cu.getImport(memento.substring(end + 1));
259 // int typeStart = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
260 // if (typeStart == -1) {
261 // //we ended with a compilation unit
262 // return frag.getCompilationUnit(memento.substring(oldEnd + 1));
266 // ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, typeStart));
267 // end = memento.indexOf(JavaElement.JEM_FIELD, oldEnd);
270 // IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
271 // return type.getField(memento.substring(end + 1));
273 // end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd);
276 // IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
278 // String methodName;
279 // end = memento.lastIndexOf(JavaElement.JEM_METHOD);
280 // String[] parameterTypes = null;
281 // if (end == oldEnd) {
282 // methodName = memento.substring(end + 1);
283 // //no parameter types
284 // parameterTypes = new String[] {};
286 // String parameters = memento.substring(oldEnd + 1);
287 // StringTokenizer mTokenizer = new StringTokenizer(parameters, new String(new char[] {JavaElement.JEM_METHOD}));
288 // parameterTypes = new String[mTokenizer.countTokens() - 1];
289 // methodName = mTokenizer.nextToken();
291 // while (mTokenizer.hasMoreTokens()) {
292 // parameterTypes[i] = mTokenizer.nextToken();
296 // return type.getMethod(methodName, parameterTypes);
299 // end = memento.indexOf(JavaElement.JEM_INITIALIZER, oldEnd);
302 // IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
303 // return type.getInitializer(Integer.parseInt(memento.substring(end + 1)));
306 // return getHandleFromMementoForSourceType(memento, cu, typeStart, memento.length());
309 * Returns the <code>IJavaElement</code> represented by the <code>String</code>
311 * @see getHandleMemento()
313 //protected IType getHandleFromMementoForSourceType(String memento, ICompilationUnit cu, int typeStart, int typeEnd) throws JavaModelException {
314 // int end = memento.lastIndexOf(JavaElement.JEM_TYPE);
315 // IType type = null;
316 // if (end == typeStart) {
317 // String typeName = memento.substring(typeStart + 1, typeEnd);
318 // type = cu.getType(typeName);
321 // String typeNames = memento.substring(typeStart + 1, typeEnd);
322 // StringTokenizer tokenizer = new StringTokenizer(typeNames, new String(new char[] {JavaElement.JEM_TYPE}));
323 // type = cu.getType(tokenizer.nextToken());
324 // while (tokenizer.hasMoreTokens()) {
325 // //deal with inner types
326 // type= type.getType(tokenizer.nextToken());
332 * @see JavaElement#getHandleMemento()
334 public String getHandleMemento(){
335 return getElementName();
338 * Returns the <code>char</code> that marks the start of this handles
339 * contribution to a memento.
341 protected char getHandleMementoDelimiter(){
342 Assert.isTrue(false, "Should not be called"); //$NON-NLS-1$
348 public IJavaProject getJavaProject(String name) {
349 return new JavaProject(ResourcesPlugin.getWorkspace().getRoot().getProject(name), this);
352 * Returns the active Java project associated with the specified
353 * resource, or <code>null</code> if no Java project yet exists
356 * @exception IllegalArgumentException if the given resource
357 * is not one of an IProject, IFolder, or IFile.
359 public IJavaProject getJavaProject(IResource resource) {
360 switch(resource.getType()){
361 case IResource.FOLDER:
362 return new JavaProject(((IFolder)resource).getProject(), this);
364 return new JavaProject(((IFile)resource).getProject(), this);
365 case IResource.PROJECT:
366 return new JavaProject((IProject)resource, this);
368 throw new IllegalArgumentException(Util.bind("element.invalidResourceForProject")); //$NON-NLS-1$
374 public IJavaProject[] getJavaProjects() throws JavaModelException {
375 ArrayList list = getChildrenOfType(JAVA_PROJECT);
376 IJavaProject[] array= new IJavaProject[list.size()];
384 //public Object[] getNonJavaResources() throws JavaModelException {
385 // return ((JavaModelInfo) getElementInfo()).getNonJavaResources();
389 * Workaround for bug 15168 circular errors not reported
390 * Returns the list of java projects before resource delta processing
393 public IJavaProject[] getOldJavaProjectsList() throws JavaModelException {
394 JavaModelManager manager = JavaModelManager.getJavaModelManager();
396 manager.javaProjectsCache == null ?
397 this.getJavaProjects() :
398 manager.javaProjectsCache;
403 public IPath getPath() {
409 public IResource getResource() {
410 return ResourcesPlugin.getWorkspace().getRoot();
415 public IResource getUnderlyingResource() throws JavaModelException {
419 * Returns the workbench associated with this object.
421 public IWorkspace getWorkspace() {
422 return ResourcesPlugin.getWorkspace();
428 //public void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
429 // if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
430 // runOperation(new MoveResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
432 // runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
437 * @see IJavaModel#refreshExternalArchives(IJavaElement[], IProgressMonitor)
439 //public void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException {
440 // if (elementsScope == null){
441 // elementsScope = new IJavaElement[] { this };
443 // JavaModelManager.getJavaModelManager().deltaProcessor.checkExternalArchiveChanges(elementsScope, monitor);
449 //public void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
450 // MultiOperation op;
451 // if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
452 // op = new RenameResourceElementsOperation(elements, destinations, renamings, force);
454 // op = new RenameElementsOperation(elements, destinations, renamings, force);
457 // runOperation(op, monitor);
460 * @see JavaElement#rootedAt(IJavaProject)
462 public IJavaElement rootedAt(IJavaProject project) {
467 * Configures and runs the <code>MultiOperation</code>.
469 //protected void runOperation(MultiOperation op, IJavaElement[] elements, IJavaElement[] siblings, String[] renamings, IProgressMonitor monitor) throws JavaModelException {
470 // op.setRenamings(renamings);
471 // if (siblings != null) {
472 // for (int i = 0; i < elements.length; i++) {
473 // op.setInsertBefore(elements[i], siblings[i]);
476 // runOperation(op, monitor);
479 * @private Debugging purposes
481 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
482 buffer.append(this.tabString(tab));
483 buffer.append("Java Model"); //$NON-NLS-1$
485 buffer.append(" (not open)"); //$NON-NLS-1$
490 * Helper method - returns the targeted item (IResource if internal or java.io.File if external),
492 * Internal items must be referred to using container relative paths.
494 //public static Object getTarget(IContainer container, IPath path, boolean checkResourceExistence) {
496 // if (path == null) return null;
498 // // lookup - inside the container
499 // if (path.getDevice() == null) { // container relative paths should not contain a device
500 // // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=18684)
501 // // (case of a workspace rooted at d:\ )
502 // IResource resource = container.findMember(path);
503 // if (resource != null){
504 // if (!checkResourceExistence ||resource.exists()) return resource;
509 // // if path is relative, it cannot be an external path
510 // // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517)
511 // if (!path.isAbsolute()) return null;
513 // // lookup - outside the container
514 // File externalFile = new File(path.toOSString());
515 // if (!checkResourceExistence) {
516 // return externalFile;
517 // } else if (existingExternalFiles.contains(externalFile)) {
518 // return externalFile;
520 // if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
521 // System.out.println("(" + Thread.currentThread() + ") [JavaModel.getTarget(...)] Checking existence of " + path.toString()); //$NON-NLS-1$ //$NON-NLS-2$
523 // if (externalFile.exists()) {
524 // // cache external file
525 // existingExternalFiles.add(externalFile);
526 // return externalFile;