Refactory: remove unused classes, imports, fields and methods.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / CopyResourceElementsOperation.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.io.ByteArrayInputStream;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Enumeration;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.Map;
20
21 import net.sourceforge.phpdt.core.IBuffer;
22 import net.sourceforge.phpdt.core.ICompilationUnit;
23 import net.sourceforge.phpdt.core.IJavaElement;
24 import net.sourceforge.phpdt.core.IJavaElementDelta;
25 import net.sourceforge.phpdt.core.IJavaModelStatus;
26 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
27 import net.sourceforge.phpdt.core.IJavaProject;
28 import net.sourceforge.phpdt.core.IPackageFragment;
29 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
30 import net.sourceforge.phpdt.core.IType;
31 import net.sourceforge.phpdt.core.JavaCore;
32 import net.sourceforge.phpdt.core.JavaModelException;
33 import net.sourceforge.phpdt.core.jdom.DOMException;
34 import net.sourceforge.phpdt.core.jdom.DOMFactory;
35 import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit;
36 import net.sourceforge.phpdt.core.jdom.IDOMNode;
37 import net.sourceforge.phpdt.internal.core.util.Util;
38
39 import org.eclipse.core.resources.IContainer;
40 import org.eclipse.core.resources.IFile;
41 import org.eclipse.core.resources.IFolder;
42 import org.eclipse.core.resources.IResource;
43 import org.eclipse.core.resources.ResourcesPlugin;
44 import org.eclipse.core.runtime.CoreException;
45 import org.eclipse.core.runtime.IPath;
46 import org.eclipse.core.runtime.Path;
47
48 /**
49  * This operation copies/moves/renames a collection of resources from their
50  * current container to a new container, optionally renaming the elements.
51  * <p>
52  * Notes:
53  * <ul>
54  * <li>If there is already an resource with the same name in the new container,
55  * the operation either overwrites or aborts, depending on the collision policy
56  * setting. The default setting is abort.
57  * 
58  * <li>When a compilation unit is copied to a new package, the package
59  * declaration in the compilation unit is automatically updated.
60  * 
61  * <li>The collection of elements being copied must all share the same type of
62  * container.
63  * 
64  * <li>This operation can be used to copy and rename elements within the same
65  * container.
66  * 
67  * <li>This operation only copies compilation units and package fragments. It
68  * does not copy package fragment roots - a platform operation must be used for
69  * that.
70  * </ul>
71  * 
72  */
73 public class CopyResourceElementsOperation extends MultiOperation {
74         /**
75          * A collection of renamed compilation units. These cus do not need to be
76          * saved as they no longer exist.
77          */
78         protected ArrayList fRenamedCompilationUnits = null;
79
80         /**
81          * Table specifying deltas for elements being copied/moved/renamed. Keyed by
82          * elements' project(s), and values are the corresponding deltas.
83          */
84         protected Map fDeltasPerProject = new HashMap(1);
85
86         /**
87          * The <code>DOMFactory</code> used to manipulate the source code of
88          * <code>ICompilationUnit</code>.
89          */
90         protected DOMFactory fFactory;
91
92         /**
93          * The list of new resources created during this operation.
94          */
95         protected ArrayList fCreatedElements;
96
97         /**
98          * When executed, this operation will copy the given resources to the given
99          * containers. The resources and destination containers must be in the
100          * correct order. If there is > 1 destination, the number of destinations
101          * must be the same as the number of resources being copied/moved.
102          */
103         public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy,
104                         IJavaElement[] destContainers, boolean force) {
105                 super(resourcesToCopy, destContainers, force);
106                 fFactory = new DOMFactory();
107         }
108
109         /**
110          * When executed, this operation will copy the given resources to the given
111          * container.
112          */
113 //      public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy,
114 //                      IJavaElement destContainer, boolean force) {
115 //              this(resourcesToCopy, new IJavaElement[] { destContainer }, force);
116 //      }
117
118         /**
119          * Returns the children of <code>source</code> which are affected by this
120          * operation. If <code>source</code> is a <code>K_SOURCE</code>, these
121          * are the <code>.java</code> files, if it is a <code>K_BINARY</code>,
122          * they are the <code>.class</code> files.
123          */
124         private IResource[] collectResourcesOfInterest(IPackageFragment source)
125                         throws JavaModelException {
126                 IJavaElement[] children = source.getChildren();
127                 int childOfInterest = IJavaElement.COMPILATION_UNIT;
128                 // if (source.getKind() == IPackageFragmentRoot.K_BINARY) {
129                 // childOfInterest = IJavaElement.CLASS_FILE;
130                 // }
131                 ArrayList correctKindChildren = new ArrayList(children.length);
132                 for (int i = 0; i < children.length; i++) {
133                         IJavaElement child = children[i];
134                         if (child.getElementType() == childOfInterest) {
135                                 correctKindChildren.add(child.getResource());
136                         }
137                 }
138                 // Gather non-java resources
139                 // Object[] nonJavaResources = source.getNonJavaResources();
140                 // int actualNonJavaResourceCount = 0;
141                 // for (int i = 0, max = nonJavaResources.length; i < max; i++){
142                 // if (nonJavaResources[i] instanceof IResource)
143                 // actualNonJavaResourceCount++;
144                 // }
145                 // IResource[] actualNonJavaResources = new
146                 // IResource[actualNonJavaResourceCount];
147                 // for (int i = 0, max = nonJavaResources.length, index = 0; i < max;
148                 // i++){
149                 // if (nonJavaResources[i] instanceof IResource)
150                 // actualNonJavaResources[index++] = (IResource)nonJavaResources[i];
151                 // }
152
153                 // if (actualNonJavaResourceCount != 0) {
154                 // int correctKindChildrenSize = correctKindChildren.size();
155                 // IResource[] result = new IResource[correctKindChildrenSize +
156                 // actualNonJavaResourceCount];
157                 // correctKindChildren.toArray(result);
158                 // System.arraycopy(actualNonJavaResources, 0, result,
159                 // correctKindChildrenSize, actualNonJavaResourceCount);
160                 // return result;
161                 // } else {
162                 IResource[] result = new IResource[correctKindChildren.size()];
163                 correctKindChildren.toArray(result);
164                 return result;
165                 // }
166         }
167
168         /**
169          * Creates any destination package fragment(s) which do not exists yet.
170          */
171         private void createNeededPackageFragments(IContainer sourceFolder,
172                         IPackageFragmentRoot root, String newFragName, boolean moveFolder)
173                         throws JavaModelException {
174                 IContainer parentFolder = (IContainer) root.getResource();
175                 JavaElementDelta projectDelta = null;
176                 String[] names = net.sourceforge.phpdt.internal.core.util.Util
177                                 .getTrimmedSimpleNames(newFragName);
178                 StringBuffer sideEffectPackageName = new StringBuffer();
179                 char[][] exclusionsPatterns = ((PackageFragmentRoot) root)
180                                 .fullExclusionPatternChars();
181                 for (int i = 0; i < names.length; i++) {
182                         String subFolderName = names[i];
183                         sideEffectPackageName.append(subFolderName);
184                         IResource subFolder = parentFolder.findMember(subFolderName);
185                         if (subFolder == null) {
186                                 // create deepest folder only if not a move (folder will be
187                                 // moved in processPackageFragmentResource)
188                                 if (!(moveFolder && i == names.length - 1)) {
189                                         createFolder(parentFolder, subFolderName, force);
190                                 }
191                                 parentFolder = parentFolder.getFolder(new Path(subFolderName));
192                                 sourceFolder = sourceFolder.getFolder(new Path(subFolderName));
193                                 if (sourceFolder.getResourceAttributes().isReadOnly()) {
194                                         parentFolder.getResourceAttributes().setReadOnly(true);
195                                 }
196                                 IPackageFragment sideEffectPackage = root
197                                                 .getPackageFragment(sideEffectPackageName.toString());
198                                 if (i < names.length - 1 // all but the last one are side
199                                                                                         // effect packages
200                                                 && !net.sourceforge.phpdt.internal.core.util.Util
201                                                                 .isExcluded(parentFolder, exclusionsPatterns)) {
202                                         if (projectDelta == null) {
203                                                 projectDelta = getDeltaFor(root.getJavaProject());
204                                         }
205                                         projectDelta.added(sideEffectPackage);
206                                 }
207                                 fCreatedElements.add(sideEffectPackage);
208                         } else {
209                                 parentFolder = (IContainer) subFolder;
210                         }
211                         sideEffectPackageName.append('.');
212                 }
213         }
214
215         /**
216          * Returns the <code>JavaElementDelta</code> for <code>javaProject</code>,
217          * creating it and putting it in <code>fDeltasPerProject</code> if it does
218          * not exist yet.
219          */
220         private JavaElementDelta getDeltaFor(IJavaProject javaProject) {
221                 JavaElementDelta delta = (JavaElementDelta) fDeltasPerProject
222                                 .get(javaProject);
223                 if (delta == null) {
224                         delta = new JavaElementDelta(javaProject);
225                         fDeltasPerProject.put(javaProject, delta);
226                 }
227                 return delta;
228         }
229
230         /**
231          * @see MultiOperation
232          */
233         protected String getMainTaskName() {
234                 return net.sourceforge.phpdt.internal.core.util.Util
235                                 .bind("operation.copyResourceProgress"); //$NON-NLS-1$
236         }
237
238         /**
239          * Sets the deltas to register the changes resulting from this operation for
240          * this source element and its destination. If the operation is a cross
241          * project operation
242          * <ul>
243          * <li>On a copy, the delta should be rooted in the dest project
244          * <li>On a move, two deltas are generated
245          * <ul>
246          * <li>one rooted in the source project
247          * <li>one rooted in the destination project
248          * </ul>
249          * </ul>
250          * If the operation is rooted in a single project, the delta is rooted in
251          * that project
252          * 
253          */
254         protected void prepareDeltas(IJavaElement sourceElement,
255                         IJavaElement destinationElement, boolean isMove) {
256                 if (net.sourceforge.phpdt.internal.core.util.Util
257                                 .isExcluded(sourceElement)
258                                 || net.sourceforge.phpdt.internal.core.util.Util
259                                                 .isExcluded(destinationElement))
260                         return;
261                 IJavaProject destProject = destinationElement.getJavaProject();
262                 if (isMove) {
263                         IJavaProject sourceProject = sourceElement.getJavaProject();
264                         getDeltaFor(sourceProject).movedFrom(sourceElement,
265                                         destinationElement);
266                         getDeltaFor(destProject).movedTo(destinationElement, sourceElement);
267                 } else {
268                         getDeltaFor(destProject).added(destinationElement);
269                 }
270         }
271
272         /**
273          * Copies/moves a compilation unit with the name <code>newCUName</code> to
274          * the destination package.<br>
275          * The package statement in the compilation unit is updated if necessary.
276          * The main type of the compilation unit is renamed if necessary.
277          * 
278          * @exception JavaModelException
279          *                if the operation is unable to complete
280          */
281         private void processCompilationUnitResource(ICompilationUnit source,
282                         IPackageFragment dest) throws JavaModelException {
283                 String newCUName = getNewNameFor(source);
284                 String destName = (newCUName != null) ? newCUName : source
285                                 .getElementName();
286                 String newContent = updatedContent(source, dest, newCUName); // null
287                                                                                                                                                 // if
288                                                                                                                                                 // unchanged
289
290                 // copy resource
291                 IFile sourceResource = (IFile) (source.isWorkingCopy() ? source
292                                 .getOriginalElement() : source).getResource();
293                 IContainer destFolder = (IContainer) dest.getResource(); // can be an
294                                                                                                                                         // IFolder
295                                                                                                                                         // or an
296                                                                                                                                         // IProject
297                 IFile destFile = destFolder.getFile(new Path(destName));
298                 if (!destFile.equals(sourceResource)) {
299                         try {
300                                 if (destFile.exists()) {
301                                         if (force) {
302                                                 // we can remove it
303                                                 deleteResource(destFile, IResource.KEEP_HISTORY);
304                                         } else {
305                                                 // abort
306                                                 throw new JavaModelException(
307                                                                 new JavaModelStatus(
308                                                                                 IJavaModelStatusConstants.NAME_COLLISION,
309                                                                                 Util
310                                                                                                 .bind(
311                                                                                                                 "status.nameCollision", destFile.getFullPath().toString()))); //$NON-NLS-1$
312                                         }
313                                 }
314                                 int flags = force ? IResource.FORCE : IResource.NONE;
315                                 if (this.isMove()) {
316                                         flags |= IResource.KEEP_HISTORY;
317                                         sourceResource.move(destFile.getFullPath(), flags,
318                                                         getSubProgressMonitor(1));
319                                 } else {
320                                         if (newContent != null)
321                                                 flags |= IResource.KEEP_HISTORY;
322                                         sourceResource.copy(destFile.getFullPath(), flags,
323                                                         getSubProgressMonitor(1));
324                                 }
325                                 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
326                         } catch (JavaModelException e) {
327                                 throw e;
328                         } catch (CoreException e) {
329                                 throw new JavaModelException(e);
330                         }
331
332                         // update new resource content
333                         try {
334                                 if (newContent != null) {
335                                         String encoding = source.getJavaProject().getOption(
336                                                         JavaCore.CORE_ENCODING, true);
337                                         destFile.setContents(new ByteArrayInputStream(
338                                                         encoding == null ? newContent.getBytes()
339                                                                         : newContent.getBytes(encoding)),
340                                                         force ? IResource.FORCE | IResource.KEEP_HISTORY
341                                                                         : IResource.KEEP_HISTORY,
342                                                         getSubProgressMonitor(1));
343                                 }
344                         } catch (IOException e) {
345                                 throw new JavaModelException(e,
346                                                 IJavaModelStatusConstants.IO_EXCEPTION);
347                         } catch (CoreException e) {
348                                 throw new JavaModelException(e);
349                         }
350
351                         // register the correct change deltas
352                         ICompilationUnit destCU = dest.getCompilationUnit(destName);
353                         prepareDeltas(source, destCU, isMove());
354                         if (newCUName != null) {
355                                 // the main type has been renamed
356                                 String oldName = source.getElementName();
357                                 oldName = oldName.substring(0, oldName.length() - 5);
358                                 String newName = newCUName;
359                                 newName = newName.substring(0, newName.length() - 5);
360                                 prepareDeltas(source.getType(oldName), destCU.getType(newName),
361                                                 isMove());
362                         }
363                 } else {
364                         if (!force) {
365                                 throw new JavaModelException(
366                                                 new JavaModelStatus(
367                                                                 IJavaModelStatusConstants.NAME_COLLISION,
368                                                                 Util
369                                                                                 .bind(
370                                                                                                 "status.nameCollision", destFile.getFullPath().toString()))); //$NON-NLS-1$
371                         }
372                         // update new resource content
373                         // in case we do a saveas on the same resource we have to simply
374                         // update the contents
375                         // see http://dev.eclipse.org/bugs/show_bug.cgi?id=9351
376                         try {
377                                 if (newContent != null) {
378                                         String encoding = source.getJavaProject().getOption(
379                                                         JavaCore.CORE_ENCODING, true);
380                                         destFile.setContents(new ByteArrayInputStream(
381                                                         encoding == null ? newContent.getBytes()
382                                                                         : newContent.getBytes(encoding)),
383                                                         force ? IResource.FORCE | IResource.KEEP_HISTORY
384                                                                         : IResource.KEEP_HISTORY,
385                                                         getSubProgressMonitor(1));
386                                 }
387                         } catch (IOException e) {
388                                 throw new JavaModelException(e,
389                                                 IJavaModelStatusConstants.IO_EXCEPTION);
390                         } catch (CoreException e) {
391                                 throw new JavaModelException(e);
392                         }
393                 }
394         }
395
396         /**
397          * Process all of the changed deltas generated by this operation.
398          */
399         protected void processDeltas() {
400                 for (Iterator deltas = this.fDeltasPerProject.values().iterator(); deltas
401                                 .hasNext();) {
402                         addDelta((IJavaElementDelta) deltas.next());
403                 }
404         }
405
406         /**
407          * @see MultiOperation This method delegates to
408          *      <code>processCompilationUnitResource</code> or
409          *      <code>processPackageFragmentResource</code>, depending on the
410          *      type of <code>element</code>.
411          */
412         protected void processElement(IJavaElement element)
413                         throws JavaModelException {
414                 IJavaElement dest = getDestinationParent(element);
415                 switch (element.getElementType()) {
416                 case IJavaElement.COMPILATION_UNIT:
417                         processCompilationUnitResource((ICompilationUnit) element,
418                                         (IPackageFragment) dest);
419                         fCreatedElements.add(((IPackageFragment) dest)
420                                         .getCompilationUnit(element.getElementName()));
421                         break;
422                 case IJavaElement.PACKAGE_FRAGMENT:
423                         processPackageFragmentResource((IPackageFragment) element,
424                                         (IPackageFragmentRoot) dest, getNewNameFor(element));
425                         break;
426                 default:
427                         throw new JavaModelException(new JavaModelStatus(
428                                         IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element));
429                 }
430         }
431
432         /**
433          * @see MultiOperation Overridden to allow special processing of
434          *      <code>JavaElementDelta</code>s and <code>fResultElements</code>.
435          */
436         protected void processElements() throws JavaModelException {
437                 fCreatedElements = new ArrayList(fElementsToProcess.length);
438                 try {
439                         super.processElements();
440                 } catch (JavaModelException jme) {
441                         throw jme;
442                 } finally {
443                         resultElements = new IJavaElement[fCreatedElements.size()];
444                         fCreatedElements.toArray(resultElements);
445                         processDeltas();
446                 }
447         }
448
449         /**
450          * Copies/moves a package fragment with the name <code>newName</code> to
451          * the destination package.<br>
452          * 
453          * @exception JavaModelException
454          *                if the operation is unable to complete
455          */
456         private void processPackageFragmentResource(IPackageFragment source,
457                         IPackageFragmentRoot root, String newName)
458                         throws JavaModelException {
459                 try {
460                         String newFragName = (newName == null) ? source.getElementName()
461                                         : newName;
462                         IPackageFragment newFrag = root.getPackageFragment(newFragName);
463                         IResource[] resources = collectResourcesOfInterest(source);
464
465                         // if isMove() can we move the folder itself ? (see
466                         // http://bugs.eclipse.org/bugs/show_bug.cgi?id=22458)
467                         boolean shouldMoveFolder = isMove()
468                                         && !newFrag.getResource().exists(); // if new pkg fragment
469                                                                                                                 // exists, it is an
470                                                                                                                 // override
471                         IFolder srcFolder = (IFolder) source.getResource();
472                         IPath destPath = newFrag.getPath();
473                         if (shouldMoveFolder) {
474                                 // check if destination is not included in source
475                                 if (srcFolder.getFullPath().isPrefixOf(destPath)) {
476                                         shouldMoveFolder = false;
477                                 } else {
478                                         // check if there are no sub-packages
479                                         IResource[] members = srcFolder.members();
480                                         for (int i = 0; i < members.length; i++) {
481                                                 if (members[i] instanceof IFolder) {
482                                                         shouldMoveFolder = false;
483                                                         break;
484                                                 }
485                                         }
486                                 }
487                         }
488                         createNeededPackageFragments((IContainer) source.getParent()
489                                         .getResource(), root, newFragName, shouldMoveFolder);
490
491                         // Process resources
492                         if (shouldMoveFolder) {
493                                 // move underlying resource
494                                 srcFolder.move(destPath, force, true /* keep history */,
495                                                 getSubProgressMonitor(1));
496                                 this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
497                         } else {
498                                 // process the leaf resources
499                                 if (resources.length > 0) {
500                                         if (isRename()) {
501                                                 if (!destPath.equals(source.getPath())) {
502                                                         moveResources(resources, destPath);
503                                                 }
504                                         } else if (isMove()) {
505                                                 // we need to delete this resource if this operation
506                                                 // wants to override existing resources
507                                                 for (int i = 0, max = resources.length; i < max; i++) {
508                                                         IResource destinationResource = ResourcesPlugin
509                                                                         .getWorkspace().getRoot().findMember(
510                                                                                         destPath.append(resources[i]
511                                                                                                         .getName()));
512                                                         if (destinationResource != null) {
513                                                                 if (force) {
514                                                                         deleteResource(destinationResource,
515                                                                                         IResource.KEEP_HISTORY);
516                                                                 } else {
517                                                                         throw new JavaModelException(
518                                                                                         new JavaModelStatus(
519                                                                                                         IJavaModelStatusConstants.NAME_COLLISION,
520                                                                                                         Util
521                                                                                                                         .bind(
522                                                                                                                                         "status.nameCollision", destinationResource.getFullPath().toString()))); //$NON-NLS-1$
523                                                                 }
524                                                         }
525                                                 }
526                                                 moveResources(resources, destPath);
527                                         } else {
528                                                 // we need to delete this resource if this operation
529                                                 // wants to override existing resources
530                                                 for (int i = 0, max = resources.length; i < max; i++) {
531                                                         IResource destinationResource = ResourcesPlugin
532                                                                         .getWorkspace().getRoot().findMember(
533                                                                                         destPath.append(resources[i]
534                                                                                                         .getName()));
535                                                         if (destinationResource != null) {
536                                                                 if (force) {
537                                                                         // we need to delete this resource if this
538                                                                         // operation wants to override existing
539                                                                         // resources
540                                                                         deleteResource(destinationResource,
541                                                                                         IResource.KEEP_HISTORY);
542                                                                 } else {
543                                                                         throw new JavaModelException(
544                                                                                         new JavaModelStatus(
545                                                                                                         IJavaModelStatusConstants.NAME_COLLISION,
546                                                                                                         Util
547                                                                                                                         .bind(
548                                                                                                                                         "status.nameCollision", destinationResource.getFullPath().toString()))); //$NON-NLS-1$
549                                                                 }
550                                                         }
551                                                 }
552                                                 copyResources(resources, destPath);
553                                         }
554                                 }
555                         }
556
557                         // Discard empty old package (if still empty after the rename)
558                         boolean isEmpty = true;
559                         if (isMove()) {
560                                 // delete remaining files in this package (.class file in the
561                                 // case where Proj=src=bin)
562                                 if (srcFolder.exists()) {
563                                         IResource[] remaingFiles = srcFolder.members();
564                                         for (int i = 0, length = remaingFiles.length; i < length; i++) {
565                                                 IResource file = remaingFiles[i];
566                                                 if (file instanceof IFile) {
567                                                         this.deleteResource(file, IResource.FORCE
568                                                                         | IResource.KEEP_HISTORY);
569                                                 } else {
570                                                         isEmpty = false;
571                                                 }
572                                         }
573                                 }
574                                 if (isEmpty) {
575                                         IResource rootResource;
576                                         // check if source is included in destination
577                                         if (destPath.isPrefixOf(srcFolder.getFullPath())) {
578                                                 rootResource = newFrag.getResource();
579                                         } else {
580                                                 rootResource = source.getParent().getResource();
581                                         }
582
583                                         // delete recursively empty folders
584                                         deleteEmptyPackageFragment(source, false, rootResource);
585                                 }
586                         }
587
588                         // Update package statement in compilation unit if needed
589                         if (!newFrag.getElementName().equals(source.getElementName())) { // if
590                                                                                                                                                                 // package
591                                                                                                                                                                 // has
592                                                                                                                                                                 // been
593                                                                                                                                                                 // renamed,
594                                                                                                                                                                 // update
595                                                                                                                                                                 // the
596                                                                                                                                                                 // compilation
597                                                                                                                                                                 // units
598                                 for (int i = 0; i < resources.length; i++) {
599                                         if (resources[i].getName().endsWith(".java")) { //$NON-NLS-1$
600                                                 // we only consider potential compilation units
601                                                 ICompilationUnit cu = newFrag
602                                                                 .getCompilationUnit(resources[i].getName());
603                                                 IDOMCompilationUnit domCU = fFactory
604                                                                 .createCompilationUnit(cu.getSource(), cu
605                                                                                 .getElementName());
606                                                 if (domCU != null) {
607                                                         updatePackageStatement(domCU, newFragName);
608                                                         IBuffer buffer = cu.getBuffer();
609                                                         if (buffer == null)
610                                                                 continue;
611                                                         String bufferContents = buffer.getContents();
612                                                         if (bufferContents == null)
613                                                                 continue;
614                                                         String domCUContents = domCU.getContents();
615                                                         String cuContents = null;
616                                                         if (domCUContents != null) {
617                                                                 cuContents = net.sourceforge.phpdt.internal.core.util.Util
618                                                                                 .normalizeCRs(domCU.getContents(),
619                                                                                                 bufferContents);
620                                                         } else {
621                                                                 // See PR
622                                                                 // http://dev.eclipse.org/bugs/show_bug.cgi?id=11285
623                                                                 cuContents = bufferContents;//$NON-NLS-1$
624                                                         }
625                                                         buffer.setContents(cuContents);
626                                                         cu.save(null, false);
627                                                 }
628                                         }
629                                 }
630                         }
631
632                         // register the correct change deltas
633                         prepareDeltas(source, newFrag, isMove() && isEmpty);
634                 } catch (DOMException dom) {
635                         throw new JavaModelException(dom,
636                                         IJavaModelStatusConstants.DOM_EXCEPTION);
637                 } catch (JavaModelException e) {
638                         throw e;
639                 } catch (CoreException ce) {
640                         throw new JavaModelException(ce);
641                 }
642         }
643
644         /**
645          * Updates the content of <code>cu</code>, modifying the type name and/or
646          * package declaration as necessary.
647          * 
648          * @return the new source
649          */
650         private String updatedContent(ICompilationUnit cu, IPackageFragment dest,
651                         String newName) throws JavaModelException {
652                 String currPackageName = cu.getParent().getElementName();
653                 String destPackageName = dest.getElementName();
654                 if (currPackageName.equals(destPackageName) && newName == null) {
655                         return null; // nothing to change
656                 } else {
657                         String typeName = cu.getElementName();
658                         typeName = typeName.substring(0, typeName.length() - 5);
659                         IDOMCompilationUnit cuDOM = null;
660                         IBuffer buffer = cu.getBuffer();
661                         if (buffer == null)
662                                 return null;
663                         char[] contents = buffer.getCharacters();
664                         if (contents == null)
665                                 return null;
666                         cuDOM = fFactory.createCompilationUnit(contents, typeName);
667                         updateTypeName(cu, cuDOM, cu.getElementName(), newName);
668                         updatePackageStatement(cuDOM, destPackageName);
669                         return cuDOM.getContents();
670                 }
671         }
672
673         /**
674          * Makes sure that <code>cu</code> declares to be in the
675          * <code>pkgName</code> package.
676          */
677         private void updatePackageStatement(IDOMCompilationUnit domCU,
678                         String pkgName) throws JavaModelException {
679                 boolean defaultPackage = pkgName
680                                 .equals(IPackageFragment.DEFAULT_PACKAGE_NAME);
681                 boolean seenPackageNode = false;
682                 Enumeration e = domCU.getChildren();
683                 while (e.hasMoreElements()) {
684                         IDOMNode node = (IDOMNode) e.nextElement();
685                         if (node.getNodeType() == IDOMNode.PACKAGE) {
686                                 if (!defaultPackage) {
687                                         node.setName(pkgName);
688                                 } else {
689                                         node.remove();
690                                 }
691                                 seenPackageNode = true;
692                                 break;
693                         }
694                 }
695                 if (!seenPackageNode && !defaultPackage) {
696                         // the cu was in a default package...no package declaration
697                         // create the new package declaration as the first child of the cu
698                         // IDOMPackage pkg = fFactory.createPackage("package " + pkgName +
699                         // ";" +
700                         // net.sourceforge.phpdt.internal.compiler.util.ProjectPrefUtil.LINE_SEPARATOR);
701                         // //$NON-NLS-1$ //$NON-NLS-2$
702                         // IDOMNode firstChild = domCU.getFirstChild();
703                         // if (firstChild != null) {
704                         // firstChild.insertSibling(pkg);
705                         // } // else the cu was empty: leave it empty
706                 }
707         }
708
709         /**
710          * Renames the main type in <code>cu</code>.
711          */
712         private void updateTypeName(ICompilationUnit cu, IDOMCompilationUnit domCU,
713                         String oldName, String newName) throws JavaModelException {
714                 if (newName != null) {
715                         if (fRenamedCompilationUnits == null) {
716                                 fRenamedCompilationUnits = new ArrayList(1);
717                         }
718                         fRenamedCompilationUnits.add(cu);
719                         String oldTypeName = oldName.substring(0, oldName.length() - 5);
720                         String newTypeName = newName.substring(0, newName.length() - 5);
721                         // update main type name
722                         IType[] types = cu.getTypes();
723                         for (int i = 0, max = types.length; i < max; i++) {
724                                 IType currentType = types[i];
725                                 if (currentType.getElementName().equals(oldTypeName)) {
726                                         IDOMNode typeNode = ((JavaElement) currentType)
727                                                         .findNode(domCU);
728                                         if (typeNode != null) {
729                                                 typeNode.setName(newTypeName);
730                                         }
731                                 }
732                         }
733                 }
734         }
735
736         /**
737          * Possible failures:
738          * <ul>
739          * <li>NO_ELEMENTS_TO_PROCESS - no elements supplied to the operation
740          * <li>INDEX_OUT_OF_BOUNDS - the number of renamings supplied to the
741          * operation does not match the number of elements that were supplied.
742          * </ul>
743          */
744         protected IJavaModelStatus verify() {
745                 IJavaModelStatus status = super.verify();
746                 if (!status.isOK()) {
747                         return status;
748                 }
749
750                 if (fRenamingsList != null
751                                 && fRenamingsList.length != fElementsToProcess.length) {
752                         return new JavaModelStatus(
753                                         IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS);
754                 }
755                 return JavaModelStatus.VERIFIED_OK;
756         }
757
758         /**
759          * @see MultiOperation
760          */
761         protected void verify(IJavaElement element) throws JavaModelException {
762                 if (element == null || !element.exists())
763                         error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);
764
765                 if (element.isReadOnly() && (isRename() || isMove()))
766                         error(IJavaModelStatusConstants.READ_ONLY, element);
767
768                 IResource resource = element.getResource();
769                 if (resource instanceof IFolder) {
770                         if (resource.isLinked()) {
771                                 error(JavaModelStatus.INVALID_RESOURCE, element);
772                         }
773                 }
774
775                 int elementType = element.getElementType();
776
777                 if (elementType == IJavaElement.COMPILATION_UNIT) {
778                         if (isMove() && ((ICompilationUnit) element).isWorkingCopy())
779                                 error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
780                 } else if (elementType != IJavaElement.PACKAGE_FRAGMENT) {
781                         error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
782                 }
783
784                 JavaElement dest = (JavaElement) getDestinationParent(element);
785                 verifyDestination(element, dest);
786                 if (fRenamings != null) {
787                         verifyRenaming(element);
788                 }
789         }
790 }