improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / PackageFragment.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 import java.util.Map;
16
17 import net.sourceforge.phpdt.core.ICompilationUnit;
18 import net.sourceforge.phpdt.core.IJavaElement;
19 import net.sourceforge.phpdt.core.IPackageFragment;
20 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
21 import net.sourceforge.phpdt.core.JavaModelException;
22 import net.sourceforge.phpdt.core.WorkingCopyOwner;
23 import net.sourceforge.phpdt.internal.core.util.MementoTokenizer;
24 import net.sourceforge.phpdt.internal.core.util.Util;
25 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
26
27 import org.eclipse.core.resources.IContainer;
28 import org.eclipse.core.resources.IResource;
29 import org.eclipse.core.runtime.CoreException;
30 import org.eclipse.core.runtime.IPath;
31 import org.eclipse.core.runtime.IProgressMonitor;
32 import org.eclipse.core.runtime.Path;
33
34
35 /**
36  * @see IPackageFragment
37  */
38 public class PackageFragment extends Openable implements IPackageFragment {
39                 /**
40          * Constant empty list of compilation units
41          */
42         protected static ICompilationUnit[] fgEmptyCompilationUnitList= new ICompilationUnit[] {};
43         /**
44          * Constructs a handle for a package fragment
45          *
46          * @see IPackageFragment
47          */
48         protected PackageFragment(PackageFragmentRoot root, String name) {
49                 super(root, name);
50         }
51         /**
52          * @see Openable
53          */
54         protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
55
56                 // check whether this pkg can be opened
57                 if (!underlyingResource.isAccessible()) throw newNotPresentException();
58
59                 int kind = getKind();
60                 String extType;
61 //              if (kind == IPackageFragmentRoot.K_SOURCE) {
62                         extType = "php"; //EXTENSION_java;
63 //              } else {
64 //                      extType = EXTENSION_class;
65 //              }
66
67                 // add compilation units/class files from resources
68                 HashSet vChildren = new HashSet();
69                 try {
70                     PackageFragmentRoot root = getPackageFragmentRoot();
71 //                      char[][] inclusionPatterns = root.fullInclusionPatternChars();
72                         char[][] exclusionPatterns = root.fullExclusionPatternChars();
73                         IResource[] members = ((IContainer) underlyingResource).members();
74                         for (int i = 0, max = members.length; i < max; i++) {
75                                 IResource child = members[i];
76                                 if (child.getType() != IResource.FOLDER
77                                                 && !Util.isExcluded(child, exclusionPatterns)) {
78                                         String extension = child.getProjectRelativePath().getFileExtension();
79                                         if (extension != null) {
80                                                 if (extension.equalsIgnoreCase(extType)) {
81                                                         IJavaElement childElement;
82 //                                                      if (kind == IPackageFragmentRoot.K_SOURCE && ProjectPrefUtil.isValidCompilationUnitName(child.getName())) {
83 //                                                              childElement = new CompilationUnit(this, child.getName(), DefaultWorkingCopyOwner.PRIMARY);
84 //                                                              vChildren.add(childElement);
85 //                                                      } else if (ProjectPrefUtil.isValidClassFileName(child.getName())) {
86 //                                                              childElement = getClassFile(child.getName());
87 //                                                              vChildren.add(childElement);
88 //                                                      }
89                                                 }
90                                         }
91                                 }
92                         }
93                 } catch (CoreException e) {
94                         throw new JavaModelException(e);
95                 }
96                 
97 //              if (kind == IPackageFragmentRoot.K_SOURCE) {
98 //                      // add primary compilation units
99 //                      ICompilationUnit[] primaryCompilationUnits = getCompilationUnits(DefaultWorkingCopyOwner.PRIMARY);
100 //                      for (int i = 0, length = primaryCompilationUnits.length; i < length; i++) {
101 //                              ICompilationUnit primary = primaryCompilationUnits[i];
102 //                              vChildren.add(primary);
103 //                      }
104 //              }
105                 
106                 IJavaElement[] children = new IJavaElement[vChildren.size()];
107                 vChildren.toArray(children);
108                 info.setChildren(children);
109                 return true;
110         }
111 ///**
112 // * Compute the children of this package fragment.
113 // *
114 // * <p>Package fragments which are folders recognize files based on the
115 // * type of the fragment
116 // * <p>Package fragments which are in a jar only recognize .class files (
117 // * @see JarPackageFragment).
118 // */
119 //protected boolean computeChildren(OpenableElementInfo info, IResource resource) throws JavaModelException {
120 //      ArrayList vChildren = new ArrayList();
121 ////    int kind = getKind();
122 //      String extType;
123 ////    if (kind == IPackageFragmentRoot.K_SOURCE) {
124 //              extType = "php"; //$NON-NLS-1$
125 ////    } else {
126 ////            extType = "class"; //$NON-NLS-1$
127 ////    }
128 //      try {
129 //              char[][] exclusionPatterns = ((PackageFragmentRoot)getPackageFragmentRoot()).fullExclusionPatternChars();
130 //              IResource[] members = ((IContainer) resource).members();
131 //              for (int i = 0, max = members.length; i < max; i++) {
132 //                      IResource child = members[i];
133 //                      if (child.getType() != IResource.FOLDER
134 //                                      && !ProjectPrefUtil.isExcluded(child, exclusionPatterns)) {
135 //                              String extension = child.getProjectRelativePath().getFileExtension();
136 //                              if (extension != null) {
137 //                                      if (extension.equalsIgnoreCase(extType)) {
138 //                                              IJavaElement childElement;
139 ////                                            if (kind == IPackageFragmentRoot.K_SOURCE && ProjectPrefUtil.isValidCompilationUnitName(child.getName())) {
140 ////                                                    childElement = getCompilationUnit(child.getName());
141 ////                                                    vChildren.add(childElement);
142 ////                                            } else if (ProjectPrefUtil.isValidClassFileName(child.getName())) {
143 ////                                                    childElement = getClassFile(child.getName());
144 ////                                                    vChildren.add(childElement);
145 ////                                            }
146 //                                      }
147 //                              }
148 //                      }
149 //              }
150 //      } catch (CoreException e) {
151 //              throw new JavaModelException(e);
152 //      }
153 //      IJavaElement[] children = new IJavaElement[vChildren.size()];
154 //      vChildren.toArray(children);
155 //      info.setChildren(children);
156 //      return true;
157 //}
158 /**
159  * Returns true if this fragment contains at least one java resource.
160  * Returns false otherwise.
161  */
162 //public boolean containsJavaResources() throws JavaModelException {
163 //      return ((PackageFragmentInfo) getElementInfo()).containsJavaResources();
164 //}
165 /**
166  * @see ISourceManipulation
167  */
168 //public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
169 //      if (container == null) {
170 //              throw new IllegalArgumentException(ProjectPrefUtil.bind("operation.nullContainer")); //$NON-NLS-1$
171 //      }
172 //      IJavaElement[] elements= new IJavaElement[] {this};
173 //      IJavaElement[] containers= new IJavaElement[] {container};
174 //      IJavaElement[] siblings= null;
175 //      if (sibling != null) {
176 //              siblings= new IJavaElement[] {sibling};
177 //      }
178 //      String[] renamings= null;
179 //      if (rename != null) {
180 //              renamings= new String[] {rename};
181 //      }
182 //      getJavaModel().copy(elements, containers, siblings, renamings, force, monitor);
183 //}
184 /**
185  * @see IPackageFragment
186  */
187 public ICompilationUnit createCompilationUnit(String name, String contents, boolean force, IProgressMonitor monitor) throws JavaModelException {
188 //      CreateCompilationUnitOperation op= new CreateCompilationUnitOperation(this, name, contents, force);
189 //      runOperation(op, monitor);
190 //      return getCompilationUnit(name);
191     return null;
192 }
193 /**
194  * @see JavaElement
195  */
196 protected Object createElementInfo() {
197         return new PackageFragmentInfo();
198 }
199 /**
200  * @see ISourceManipulation
201  */
202 //public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
203 //      IJavaElement[] elements = new IJavaElement[] {this};
204 //      getJavaModel().delete(elements, force, monitor);
205 //}
206 ///**
207 // * @see Openable
208 // */
209 //protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
210 //      
211 //      return computeChildren(info, underlyingResource);
212 //}
213 ///**
214 // * @see IPackageFragment#getClassFile(String)
215 // */
216 //public IClassFile getClassFile(String name) {
217 //      return new ClassFile(this, name);
218 //}
219 /**
220  * Returns a the collection of class files in this - a folder package fragment which has a root
221  * that has its kind set to <code>IPackageFragmentRoot.K_Source</code> does not
222  * recognize class files.
223  *
224  * @see IPackageFragment#getClassFiles()
225  */
226 //public IClassFile[] getClassFiles() throws JavaModelException {
227 //      if (getKind() == IPackageFragmentRoot.K_SOURCE) {
228 //              return fgEmptyClassFileList;
229 //      }
230 //      
231 //      ArrayList list = getChildrenOfType(CLASS_FILE);
232 //      IClassFile[] array= new IClassFile[list.size()];
233 //      list.toArray(array);
234 //      return array;
235 //}
236 /**
237  * @see IPackageFragment#getCompilationUnit(String)
238  * @exception IllegalArgumentExcpetion if the name does not end with a php file extension
239  */
240 public ICompilationUnit getCompilationUnit(String cuName) {
241         if (!  PHPFileUtil.isValidPHPUnitName(cuName)) {
242                 throw new IllegalArgumentException(Util.bind("convention.unit.notJavaName")); //$NON-NLS-1$
243         }
244         return new CompilationUnit(this, cuName, DefaultWorkingCopyOwner.PRIMARY);
245 }
246 /**
247  * @see IPackageFragment#getCompilationUnits()
248  */
249 public ICompilationUnit[] getCompilationUnits() throws JavaModelException {
250         if (getKind() == IPackageFragmentRoot.K_BINARY) {
251                 return fgEmptyCompilationUnitList;
252         }
253         
254         ArrayList list = getChildrenOfType(COMPILATION_UNIT);
255         ICompilationUnit[] array= new ICompilationUnit[list.size()];
256         list.toArray(array);
257         return array;
258 }
259 /**
260  * @see IJavaElement
261  */
262 public int getElementType() {
263         return PACKAGE_FRAGMENT;
264 }
265 /*
266  * @see JavaElement
267  */
268 public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
269         switch (token.charAt(0)) {
270                 case JEM_COUNT:
271                         return getHandleUpdatingCountFromMemento(memento, owner);
272 //              case JEM_CLASSFILE:
273 //                      String classFileName = memento.nextToken();
274 //                      JavaElement classFile = (JavaElement)getClassFile(classFileName);
275 //                      return classFile.getHandleFromMemento(memento, owner);
276                 case JEM_COMPILATIONUNIT:
277                         String cuName = memento.nextToken();
278                         JavaElement cu = new CompilationUnit(this, cuName, owner);
279                         return cu.getHandleFromMemento(memento, owner);
280         }
281         return null;
282 }
283 /**
284  * @see JavaElement#getHandleMementoDelimiter()
285  */
286 protected char getHandleMementoDelimiter() {
287         return JavaElement.JEM_PACKAGEFRAGMENT;
288 }
289 /**
290  * @see IPackageFragment#getKind()
291  */
292 public int getKind() throws JavaModelException {
293         return ((IPackageFragmentRoot)getParent()).getKind();
294 }
295 /**
296  * Returns an array of non-java resources contained in the receiver.
297  */
298 //public Object[] getNonJavaResources() throws JavaModelException {
299 //      if (this.isDefaultPackage()) {
300 //              // We don't want to show non java resources of the default package (see PR #1G58NB8)
301 //              return JavaElementInfo.NO_NON_JAVA_RESOURCES;
302 //      } else {
303 //              return ((PackageFragmentInfo) getElementInfo()).getNonJavaResources(getResource(), (PackageFragmentRoot)getPackageFragmentRoot());
304 //      }
305 //}
306 /**
307  * @see IJavaElement#getPath()
308  */
309 public IPath getPath() {
310         PackageFragmentRoot root = this.getPackageFragmentRoot();
311         if (root.isArchive()) {
312                 return root.getPath();
313         } else {
314 //              return root.getPath().append(this.getElementName().replace('.', '/'));
315                 return root.getPath().append(this.getElementName());
316         }
317 }
318 /**
319  * @see IJavaElement#getResource()
320  */
321 public IResource getResource() {
322         PackageFragmentRoot root = this.getPackageFragmentRoot();
323         if (root.isArchive()) {
324                 return root.getResource();
325         } else {
326                 String elementName = this.getElementName();
327                 if (elementName.length() == 0) {
328                         return root.getResource();
329                 } else {
330 //                      return ((IContainer)root.getResource()).getFolder(new Path(this.getElementName().replace('.', '/')));
331                         return ((IContainer)root.getResource()).getFolder(new Path(this.getElementName()));
332                 }
333         }
334 }
335 /**
336  * @see IJavaElement#getUnderlyingResource()
337  */
338 public IResource getUnderlyingResource() throws JavaModelException {
339         IResource rootResource = parent.getUnderlyingResource();
340         if (rootResource == null) {
341                 //jar package fragment root that has no associated resource
342                 return null;
343         }
344         // the underlying resource may be a folder or a project (in the case that the project folder
345         // is atually the package fragment root)
346 //      if (rootResource.getType() == IResource.FOLDER || rootResource.getType() == IResource.PROJECT) {
347 //              IContainer folder = (IContainer) rootResource;
348 //              String[] segs = Signature.getSimpleNames(fName);
349 //              for (int i = 0; i < segs.length; ++i) {
350 //                      IResource child = folder.findMember(segs[i]);
351 //                      if (child == null || child.getType() != IResource.FOLDER) {
352 //                              throw newNotPresentException();
353 //                      }
354 //                      folder = (IFolder) child;
355 //              }
356 //              return folder;
357 //      } else {
358                 return rootResource;
359 //      }
360 }
361 /**
362  * @see IPackageFragment#hasSubpackages()
363  */
364 //public boolean hasSubpackages() throws JavaModelException {
365 //      IJavaElement[] packages= ((IPackageFragmentRoot)getParent()).getChildren();
366 //      String name = getElementName();
367 //      int nameLength = name.length();
368 //      String packageName = isDefaultPackage() ? name : name+"."; //$NON-NLS-1$
369 //      for (int i= 0; i < packages.length; i++) {
370 //              String otherName = packages[i].getElementName();
371 //              if (otherName.length() > nameLength && otherName.startsWith(packageName)) {
372 //                      return true;
373 //              }
374 //      }
375 //      return false;
376 //}
377 /**
378  * @see IPackageFragment#isDefaultPackage()
379  */
380 public boolean isDefaultPackage() {
381         return this.getElementName().length() == 0;
382 }
383 /**
384  * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
385  */
386 //public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
387 //      if (container == null) {
388 //              throw new IllegalArgumentException(ProjectPrefUtil.bind("operation.nullContainer")); //$NON-NLS-1$
389 //      }
390 //      IJavaElement[] elements= new IJavaElement[] {this};
391 //      IJavaElement[] containers= new IJavaElement[] {container};
392 //      IJavaElement[] siblings= null;
393 //      if (sibling != null) {
394 //              siblings= new IJavaElement[] {sibling};
395 //      }
396 //      String[] renamings= null;
397 //      if (rename != null) {
398 //              renamings= new String[] {rename};
399 //      }
400 //      getJavaModel().move(elements, containers, siblings, renamings, force, monitor);
401 //}
402 //protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
403 //      if (!this.resourceExists()) throw newNotPresentException();
404 //      super.openWhenClosed(pm);
405 //}
406 /**
407  * Recomputes the children of this element, based on the current state
408  * of the workbench.
409  */
410 //public void refreshChildren() {
411 //      try {
412 //              OpenableElementInfo info= (OpenableElementInfo)getElementInfo();
413 //              computeChildren(info, getResource());
414 //      } catch (JavaModelException e) {
415 //              // do nothing.
416 //      }
417 //}
418 /**
419  * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
420  */
421 //public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
422 //      if (name == null) {
423 //              throw new IllegalArgumentException(ProjectPrefUtil.bind("element.nullName")); //$NON-NLS-1$
424 //      }
425 //      IJavaElement[] elements= new IJavaElement[] {this};
426 //      IJavaElement[] dests= new IJavaElement[] {this.getParent()};
427 //      String[] renamings= new String[] {name};
428 //      getJavaModel().rename(elements, dests, renamings, force, monitor);
429 //}
430 ///*
431 // * @see JavaElement#rootedAt(IJavaProject)
432 // */
433 //public IJavaElement rootedAt(IJavaProject project) {
434 //      return
435 //              new PackageFragment(
436 //                      (IPackageFragmentRoot)((JavaElement)parent).rootedAt(project), 
437 //                      name);
438 //}
439 /**
440  * Debugging purposes
441  */
442 protected void toStringChildren(int tab, StringBuffer buffer, Object info) {
443         if (tab == 0) {
444                 super.toStringChildren(tab, buffer, info);
445         }
446 }
447 /**
448  * Debugging purposes
449  */
450 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
451         buffer.append(this.tabString(tab));
452         if (getElementName().length() == 0) {
453                 buffer.append("[default]"); //$NON-NLS-1$
454         } else {
455                 buffer.append(getElementName());
456         }
457         if (info == null) {
458                 buffer.append(" (not open)"); //$NON-NLS-1$
459         } else {
460                 if (tab > 0) {
461                         buffer.append(" (...)"); //$NON-NLS-1$
462                 }
463         }
464 }
465 }