Changes:
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / JavaModel.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
12
13 import java.util.ArrayList;
14 import java.util.HashSet;
15
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;
20
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;
30
31
32 /**
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.
37  *
38  * @see IJavaModel
39  */
40 public class JavaModel extends Openable implements IJavaModel {
41
42         /**
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.
46          */ 
47         public static HashSet existingExternalFiles = new HashSet();
48                 
49 /**
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
53  * access to it.
54  * 
55  * @exception Error if called more than once
56  */
57 protected JavaModel() throws Error {
58         super(JAVA_MODEL, null, "" /*workspace has empty name*/); //$NON-NLS-1$
59 }
60 /*
61  * @see IJavaModel
62  */
63 //public boolean contains(IResource resource) {
64 //      switch (resource.getType()) {
65 //              case IResource.ROOT:
66 //              case IResource.PROJECT:
67 //                      return true;
68 //      }
69 //      // file or folder
70 //      IJavaProject[] projects;
71 //      try {
72 //              projects = this.getJavaProjects();
73 //      } catch (JavaModelException e) {
74 //              return false;
75 //      }
76 //      for (int i = 0, length = projects.length; i < length; i++) {
77 //              JavaProject project = (JavaProject)projects[i];
78 //      
79 //              if (!project.contains(resource)) {
80 //                      return false;
81 //              }
82 //      }
83 //      return true;
84 //}
85 /**
86  * @see IJavaModel
87  */
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);
91 //      } else {
92 //              runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
93 //      }
94 //}
95 /**
96  * Returns a new element info for this element.
97  */
98 //protected OpenableElementInfo createElementInfo() {
99 //      return new JavaModelInfo();
100 //}
101
102 /**
103  * @see IJavaModel
104  */
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);
108 //      } else {
109 //              runOperation(new DeleteElementsOperation(elements, force), monitor);
110 //      }
111 //}
112 /**
113  * Finds the given project in the list of the java model's children.
114  * Returns null if not found.
115  */
116 public IJavaProject findJavaProject(IProject project) {
117         try {
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())) {
122                                 return javaProject;
123                         }
124                 }
125         } catch (JavaModelException e) {
126         }
127         return null;
128 }
129
130 /**
131  * Flushes the cache of external files known to be existing.
132  */
133 public static void flushExternalFileCache() {
134         existingExternalFiles = new HashSet();
135 }
136
137 /**
138  */
139 //protected boolean generateInfos(
140 //      OpenableElementInfo info,
141 //      IProgressMonitor pm,
142 //      Map newElements,
143 //      IResource underlyingResource)   throws JavaModelException {
144 //
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));
152 //              }
153 //      }
154 //      return true;
155 //}
156 /**
157  * Returns the <code>IJavaElement</code> represented by the <code>String</code>
158  * memento.
159  * @see getHandleMemento()
160  */
161 //protected IJavaElement getHandleFromMementoForBinaryMembers(String memento, IPackageFragmentRoot root, int rootEnd, int end) throws JavaModelException {
162 //
163 //      //deal with class file and binary members
164 //      IPackageFragment frag = null;
165 //      if (rootEnd == end - 1) {
166 //              //default package
167 //              frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
168 //      } else {
169 //              frag= root.getPackageFragment(memento.substring(rootEnd + 1, end));
170 //      }
171 //      int oldEnd = end;
172 //      end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
173 //      if (end == -1) {
174 //              //we ended with a class file 
175 //              return frag.getClassFile(memento.substring(oldEnd + 1));
176 //      }
177 //      IClassFile cf = frag.getClassFile(memento.substring(oldEnd + 1, end));
178 //      oldEnd = end;
179 //      end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
180 //      oldEnd = end;
181 //      end = memento.indexOf(JavaElement.JEM_FIELD, end);
182 //      if (end != -1) {
183 //              //binary field
184 //              IType type = cf.getType();
185 //              return type.getField(memento.substring(end + 1));
186 //      }
187 //      end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd);
188 //      if (end != -1) {
189 //              //binary method
190 //              oldEnd = end;
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[] {};
199 //              } else {
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();
204 //                      int i = 0;
205 //                      while (tokenizer.hasMoreTokens()) {
206 //                              parameterTypes[i] = tokenizer.nextToken();
207 //                              i++;
208 //                      }
209 //              }
210 //              return type.getMethod(methodName, parameterTypes);
211 //      }
212 //
213 //      //binary type
214 //      return cf.getType();
215 //}
216 /**
217  * Returns the <code>IPackageFragmentRoot</code> represented by the <code>String</code>
218  * memento.
219  * @see getHandleMemento()
220  */
221 //protected IPackageFragmentRoot getHandleFromMementoForRoot(String memento, JavaProject project, int projectEnd, int rootEnd) {
222 //      String rootName = null;
223 //      if (rootEnd == projectEnd - 1) {
224 //              //default root
225 //              rootName = IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH;
226 //      } else {
227 //              rootName = memento.substring(projectEnd + 1, rootEnd);
228 //      }
229 //      return project.getPackageFragmentRoot(new Path(rootName));
230 //}
231 /**
232  * Returns the <code>IJavaElement</code> represented by the <code>String</code>
233  * memento.
234  * @see getHandleMemento()
235  */
236 //protected IJavaElement getHandleFromMementoForSourceMembers(String memento, IPackageFragmentRoot root, int rootEnd, int end) throws JavaModelException {
237 //
238 //      //deal with compilation units and source members
239 //      IPackageFragment frag = null;
240 //      if (rootEnd == end - 1) {
241 //              //default package
242 //              frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
243 //      } else {
244 //              frag= root.getPackageFragment(memento.substring(rootEnd + 1, end));
245 //      }
246 //      int oldEnd = end;
247 //      end = memento.indexOf(JavaElement.JEM_PACKAGEDECLARATION, end);
248 //      if (end != -1) {
249 //              //package declaration
250 //              ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, end));
251 //              return cu.getPackageDeclaration(memento.substring(end + 1));
252 //      }
253 //      end = memento.indexOf(JavaElement.JEM_IMPORTDECLARATION, oldEnd);
254 //      if (end != -1) {
255 //              //import declaration
256 //              ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, end));
257 //              return cu.getImport(memento.substring(end + 1));
258 //      }
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));
263 //      }
264 //
265 //      //source members
266 //      ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, typeStart));
267 //      end = memento.indexOf(JavaElement.JEM_FIELD, oldEnd);
268 //      if (end != -1) {
269 //              //source field
270 //              IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
271 //              return type.getField(memento.substring(end + 1));
272 //      }
273 //      end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd);
274 //      if (end != -1) {
275 //              //source method
276 //              IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
277 //              oldEnd = 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[] {};
285 //              } else {
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();
290 //                      int i = 0;
291 //                      while (mTokenizer.hasMoreTokens()) {
292 //                              parameterTypes[i] = mTokenizer.nextToken();
293 //                              i++;
294 //                      }
295 //              }
296 //              return type.getMethod(methodName, parameterTypes);
297 //      }
298 //      
299 //      end = memento.indexOf(JavaElement.JEM_INITIALIZER, oldEnd);
300 //      if (end != -1 ) {
301 //              //initializer
302 //              IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
303 //              return type.getInitializer(Integer.parseInt(memento.substring(end + 1)));
304 //      }
305 //      //source type
306 //      return getHandleFromMementoForSourceType(memento, cu, typeStart, memento.length());
307 //}
308 /**
309  * Returns the <code>IJavaElement</code> represented by the <code>String</code>
310  * memento.
311  * @see getHandleMemento()
312  */
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);
319 //              
320 //      } else {
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());
327 //              }
328 //      }
329 //      return type;
330 //}
331 /**
332  * @see JavaElement#getHandleMemento()
333  */
334 public String getHandleMemento(){
335         return getElementName();
336 }
337 /**
338  * Returns the <code>char</code> that marks the start of this handles
339  * contribution to a memento.
340  */
341 protected char getHandleMementoDelimiter(){
342         Assert.isTrue(false, "Should not be called"); //$NON-NLS-1$
343         return 0;
344 }
345 /**
346  * @see IJavaModel
347  */
348 public IJavaProject getJavaProject(String name) {
349         return new JavaProject(ResourcesPlugin.getWorkspace().getRoot().getProject(name), this);
350 }
351 /**
352  * Returns the active Java project associated with the specified
353  * resource, or <code>null</code> if no Java project yet exists
354  * for the resource.
355  *
356  * @exception IllegalArgumentException if the given resource
357  * is not one of an IProject, IFolder, or IFile.
358  */
359 public IJavaProject getJavaProject(IResource resource) {
360         switch(resource.getType()){
361                 case IResource.FOLDER:
362                         return new JavaProject(((IFolder)resource).getProject(), this);
363                 case IResource.FILE:
364                         return new JavaProject(((IFile)resource).getProject(), this);
365                 case IResource.PROJECT:
366                         return new JavaProject((IProject)resource, this);
367                 default:
368                         throw new IllegalArgumentException(Util.bind("element.invalidResourceForProject")); //$NON-NLS-1$
369         }
370 }
371 /**
372  * @see IJavaModel
373  */
374 public IJavaProject[] getJavaProjects() throws JavaModelException {
375         ArrayList list = getChildrenOfType(JAVA_PROJECT);
376         IJavaProject[] array= new IJavaProject[list.size()];
377         list.toArray(array);
378         return array;
379
380 }
381 ///**
382 // * @see IJavaModel
383 // */
384 //public Object[] getNonJavaResources() throws JavaModelException {
385 //              return ((JavaModelInfo) getElementInfo()).getNonJavaResources();
386 //}
387
388 /**
389  * Workaround for bug 15168 circular errors not reported 
390  * Returns the list of java projects before resource delta processing
391  * has started.
392  */
393 public IJavaProject[] getOldJavaProjectsList() throws JavaModelException {
394         JavaModelManager manager = JavaModelManager.getJavaModelManager();
395         return 
396                 manager.javaProjectsCache == null ? 
397                         this.getJavaProjects() : 
398                         manager.javaProjectsCache; 
399 }
400 /*
401  * @see IJavaElement
402  */
403 public IPath getPath() {
404         return Path.ROOT;
405 }
406 /*
407  * @see IJavaElement
408  */
409 public IResource getResource() {
410         return ResourcesPlugin.getWorkspace().getRoot();
411 }
412 /**
413  * @see IOpenable
414  */
415 public IResource getUnderlyingResource() throws JavaModelException {
416         return null;
417 }
418 /**
419  * Returns the workbench associated with this object.
420  */
421 public IWorkspace getWorkspace() {
422         return ResourcesPlugin.getWorkspace();
423 }
424
425 /**
426  * @see IJavaModel
427  */
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);
431 //      } else {
432 //              runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
433 //      }
434 //}
435
436 /**
437  * @see IJavaModel#refreshExternalArchives(IJavaElement[], IProgressMonitor)
438  */
439 //public void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException {
440 //      if (elementsScope == null){
441 //              elementsScope = new IJavaElement[] { this };
442 //      }
443 //      JavaModelManager.getJavaModelManager().deltaProcessor.checkExternalArchiveChanges(elementsScope, monitor);
444 //}
445
446 /**
447  * @see IJavaModel
448  */
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);
453 //      } else {
454 //              op = new RenameElementsOperation(elements, destinations, renamings, force);
455 //      }
456 //      
457 //      runOperation(op, monitor);
458 //}
459 /*
460  * @see JavaElement#rootedAt(IJavaProject)
461  */
462 public IJavaElement rootedAt(IJavaProject project) {
463         return this;
464
465 }
466 /**
467  * Configures and runs the <code>MultiOperation</code>.
468  */
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]);
474 //              }
475 //      }
476 //      runOperation(op, monitor);
477 //}
478 /**
479  * @private Debugging purposes
480  */
481 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
482         buffer.append(this.tabString(tab));
483         buffer.append("Java Model"); //$NON-NLS-1$
484         if (info == null) {
485                 buffer.append(" (not open)"); //$NON-NLS-1$
486         }
487 }
488
489 /**
490  * Helper method - returns the targeted item (IResource if internal or java.io.File if external), 
491  * or null if unbound
492  * Internal items must be referred to using container relative paths.
493  */
494 //public static Object getTarget(IContainer container, IPath path, boolean checkResourceExistence) {
495 //
496 //      if (path == null) return null;
497 //      
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;
505 //                      return null;
506 //              }
507 //      }
508 //      
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; 
512 //
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;
519 //      } else { 
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$
522 //              }
523 //              if (externalFile.exists()) {
524 //                      // cache external file
525 //                      existingExternalFiles.add(externalFile);
526 //                      return externalFile;
527 //              }
528 //      }
529 //      return null;    
530 //}
531 }