001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.reorg;
011:
012: import java.net.URI;
013: import java.util.ArrayList;
014: import java.util.Arrays;
015: import java.util.Collection;
016: import java.util.HashMap;
017: import java.util.HashSet;
018: import java.util.Iterator;
019: import java.util.List;
020: import java.util.Map;
021: import java.util.Set;
022:
023: import org.eclipse.core.runtime.Assert;
024:
025: import org.eclipse.core.resources.IFile;
026: import org.eclipse.core.resources.IFolder;
027: import org.eclipse.core.resources.IProject;
028: import org.eclipse.core.resources.IResource;
029:
030: import org.eclipse.ui.IWorkingSet;
031:
032: import org.eclipse.jdt.core.IClassFile;
033: import org.eclipse.jdt.core.ICompilationUnit;
034: import org.eclipse.jdt.core.IJavaElement;
035: import org.eclipse.jdt.core.IJavaProject;
036: import org.eclipse.jdt.core.IMember;
037: import org.eclipse.jdt.core.IMethod;
038: import org.eclipse.jdt.core.IPackageFragment;
039: import org.eclipse.jdt.core.IPackageFragmentRoot;
040: import org.eclipse.jdt.core.ISourceRange;
041: import org.eclipse.jdt.core.IType;
042: import org.eclipse.jdt.core.JavaCore;
043: import org.eclipse.jdt.core.JavaModelException;
044: import org.eclipse.jdt.core.Signature;
045:
046: import org.eclipse.jdt.internal.corext.SourceRange;
047: import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
048: import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
049: import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
050: import org.eclipse.jdt.internal.corext.util.Messages;
051:
052: public class ReorgUtils {
053:
054: //workaround for bug 18311
055: private static final ISourceRange fgUnknownRange = new SourceRange(
056: -1, 0);
057:
058: private ReorgUtils() {
059: }
060:
061: public static boolean isArchiveMember(IJavaElement[] elements) {
062: for (int i = 0; i < elements.length; i++) {
063: IJavaElement element = elements[i];
064: IPackageFragmentRoot root = (IPackageFragmentRoot) element
065: .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
066: if (root != null && root.isArchive())
067: return true;
068: }
069: return false;
070: }
071:
072: public static boolean containsOnlyProjects(List elements) {
073: if (elements.isEmpty())
074: return false;
075: for (Iterator iter = elements.iterator(); iter.hasNext();) {
076: if (!isProject(iter.next()))
077: return false;
078: }
079: return true;
080: }
081:
082: public static boolean isProject(Object element) {
083: return (element instanceof IJavaProject)
084: || (element instanceof IProject);
085: }
086:
087: public static boolean isInsideCompilationUnit(IJavaElement element) {
088: return !(element instanceof ICompilationUnit)
089: && hasAncestorOfType(element,
090: IJavaElement.COMPILATION_UNIT);
091: }
092:
093: public static boolean isInsideClassFile(IJavaElement element) {
094: return !(element instanceof IClassFile)
095: && hasAncestorOfType(element, IJavaElement.CLASS_FILE);
096: }
097:
098: public static boolean hasAncestorOfType(IJavaElement element,
099: int type) {
100: return element.getAncestor(type) != null;
101: }
102:
103: /*
104: * May be <code>null</code>.
105: */
106: public static ICompilationUnit getCompilationUnit(
107: IJavaElement javaElement) {
108: if (javaElement instanceof ICompilationUnit)
109: return (ICompilationUnit) javaElement;
110: return (ICompilationUnit) javaElement
111: .getAncestor(IJavaElement.COMPILATION_UNIT);
112: }
113:
114: /*
115: * some of the returned elements may be <code>null</code>.
116: */
117: public static ICompilationUnit[] getCompilationUnits(
118: IJavaElement[] javaElements) {
119: ICompilationUnit[] result = new ICompilationUnit[javaElements.length];
120: for (int i = 0; i < javaElements.length; i++) {
121: result[i] = getCompilationUnit(javaElements[i]);
122: }
123: return result;
124: }
125:
126: public static IResource getResource(IJavaElement element) {
127: if (element instanceof ICompilationUnit)
128: return ((ICompilationUnit) element).getPrimary()
129: .getResource();
130: else
131: return element.getResource();
132: }
133:
134: public static IResource[] getResources(IJavaElement[] elements) {
135: IResource[] result = new IResource[elements.length];
136: for (int i = 0; i < elements.length; i++) {
137: result[i] = ReorgUtils.getResource(elements[i]);
138: }
139: return result;
140: }
141:
142: public static String getName(IResource resource) {
143: String pattern = createNamePattern(resource);
144: String[] args = createNameArguments(resource);
145: return Messages.format(pattern, args);
146: }
147:
148: private static String createNamePattern(IResource resource) {
149: switch (resource.getType()) {
150: case IResource.FILE:
151: return RefactoringCoreMessages.ReorgUtils_0;
152: case IResource.FOLDER:
153: return RefactoringCoreMessages.ReorgUtils_1;
154: case IResource.PROJECT:
155: return RefactoringCoreMessages.ReorgUtils_2;
156: default:
157: Assert.isTrue(false);
158: return null;
159: }
160: }
161:
162: private static String[] createNameArguments(IResource resource) {
163: return new String[] { resource.getName() };
164: }
165:
166: public static String getName(IJavaElement element)
167: throws JavaModelException {
168: String pattern = createNamePattern(element);
169: String[] args = createNameArguments(element);
170: return Messages.format(pattern, args);
171: }
172:
173: private static String[] createNameArguments(IJavaElement element)
174: throws JavaModelException {
175: switch (element.getElementType()) {
176: case IJavaElement.CLASS_FILE:
177: return new String[] { element.getElementName() };
178: case IJavaElement.COMPILATION_UNIT:
179: return new String[] { element.getElementName() };
180: case IJavaElement.FIELD:
181: return new String[] { element.getElementName() };
182: case IJavaElement.IMPORT_CONTAINER:
183: return new String[0];
184: case IJavaElement.IMPORT_DECLARATION:
185: return new String[] { element.getElementName() };
186: case IJavaElement.INITIALIZER:
187: return new String[0];
188: case IJavaElement.JAVA_PROJECT:
189: return new String[] { element.getElementName() };
190: case IJavaElement.METHOD:
191: return new String[] { element.getElementName() };
192: case IJavaElement.PACKAGE_DECLARATION:
193: if (JavaElementUtil.isDefaultPackage(element))
194: return new String[0];
195: else
196: return new String[] { element.getElementName() };
197: case IJavaElement.PACKAGE_FRAGMENT:
198: return new String[] { element.getElementName() };
199: case IJavaElement.PACKAGE_FRAGMENT_ROOT:
200: return new String[] { element.getElementName() };
201: case IJavaElement.TYPE:
202: IType type = (IType) element;
203: String name = type.getElementName();
204: if (name.length() == 0 && type.isAnonymous()) {
205: String super className = Signature.getSimpleName(type
206: .getSuperclassName());
207: return new String[] { Messages.format(
208: RefactoringCoreMessages.ReorgUtils_19,
209: super className) };
210: }
211: return new String[] { element.getElementName() };
212: default:
213: Assert.isTrue(false);
214: return null;
215: }
216: }
217:
218: private static String createNamePattern(IJavaElement element)
219: throws JavaModelException {
220: switch (element.getElementType()) {
221: case IJavaElement.CLASS_FILE:
222: return RefactoringCoreMessages.ReorgUtils_3;
223: case IJavaElement.COMPILATION_UNIT:
224: return RefactoringCoreMessages.ReorgUtils_4;
225: case IJavaElement.FIELD:
226: return RefactoringCoreMessages.ReorgUtils_5;
227: case IJavaElement.IMPORT_CONTAINER:
228: return RefactoringCoreMessages.ReorgUtils_6;
229: case IJavaElement.IMPORT_DECLARATION:
230: return RefactoringCoreMessages.ReorgUtils_7;
231: case IJavaElement.INITIALIZER:
232: return RefactoringCoreMessages.ReorgUtils_8;
233: case IJavaElement.JAVA_PROJECT:
234: return RefactoringCoreMessages.ReorgUtils_9;
235: case IJavaElement.METHOD:
236: if (((IMethod) element).isConstructor())
237: return RefactoringCoreMessages.ReorgUtils_10;
238: else
239: return RefactoringCoreMessages.ReorgUtils_11;
240: case IJavaElement.PACKAGE_DECLARATION:
241: return RefactoringCoreMessages.ReorgUtils_12;
242: case IJavaElement.PACKAGE_FRAGMENT:
243: if (JavaElementUtil.isDefaultPackage(element))
244: return RefactoringCoreMessages.ReorgUtils_13;
245: else
246: return RefactoringCoreMessages.ReorgUtils_14;
247: case IJavaElement.PACKAGE_FRAGMENT_ROOT:
248: if (isSourceFolder(element))
249: return RefactoringCoreMessages.ReorgUtils_15;
250: if (isClassFolder(element))
251: return RefactoringCoreMessages.ReorgUtils_16;
252: return RefactoringCoreMessages.ReorgUtils_17;
253: case IJavaElement.TYPE:
254: IType type = (IType) element;
255: if (type.getElementName().length() == 0
256: && type.isAnonymous())
257: return RefactoringCoreMessages.ReorgUtils_20;
258: return RefactoringCoreMessages.ReorgUtils_18;
259: default:
260: Assert.isTrue(false);
261: return null;
262: }
263: }
264:
265: public static IResource[] getResources(List elements) {
266: List resources = new ArrayList(elements.size());
267: for (Iterator iter = elements.iterator(); iter.hasNext();) {
268: Object element = iter.next();
269: if (element instanceof IResource)
270: resources.add(element);
271: }
272: return (IResource[]) resources.toArray(new IResource[resources
273: .size()]);
274: }
275:
276: public static IJavaElement[] getJavaElements(List elements) {
277: List resources = new ArrayList(elements.size());
278: for (Iterator iter = elements.iterator(); iter.hasNext();) {
279: Object element = iter.next();
280: if (element instanceof IJavaElement)
281: resources.add(element);
282: }
283: return (IJavaElement[]) resources
284: .toArray(new IJavaElement[resources.size()]);
285: }
286:
287: public static IWorkingSet[] getWorkingSets(List elements) {
288: List result = new ArrayList(1);
289: for (Iterator iter = elements.iterator(); iter.hasNext();) {
290: Object element = iter.next();
291: if (element instanceof IWorkingSet) {
292: result.add(element);
293: }
294: }
295: return (IWorkingSet[]) result.toArray(new IWorkingSet[result
296: .size()]);
297: }
298:
299: public static boolean hasSourceAvailable(IMember member)
300: throws JavaModelException {
301: return !member.isBinary()
302: || (member.getSourceRange() != null && !fgUnknownRange
303: .equals(member.getSourceRange()));
304: }
305:
306: public static IResource[] setMinus(IResource[] setToRemoveFrom,
307: IResource[] elementsToRemove) {
308: Set setMinus = new HashSet(setToRemoveFrom.length
309: - setToRemoveFrom.length);
310: setMinus.addAll(Arrays.asList(setToRemoveFrom));
311: setMinus.removeAll(Arrays.asList(elementsToRemove));
312: return (IResource[]) setMinus.toArray(new IResource[setMinus
313: .size()]);
314: }
315:
316: public static IJavaElement[] setMinus(
317: IJavaElement[] setToRemoveFrom,
318: IJavaElement[] elementsToRemove) {
319: Set setMinus = new HashSet(setToRemoveFrom.length
320: - setToRemoveFrom.length);
321: setMinus.addAll(Arrays.asList(setToRemoveFrom));
322: setMinus.removeAll(Arrays.asList(elementsToRemove));
323: return (IJavaElement[]) setMinus
324: .toArray(new IJavaElement[setMinus.size()]);
325: }
326:
327: public static IJavaElement[] union(IJavaElement[] set1,
328: IJavaElement[] set2) {
329: List union = new ArrayList(set1.length + set2.length);//use lists to avoid sequence problems
330: addAll(set1, union);
331: addAll(set2, union);
332: return (IJavaElement[]) union.toArray(new IJavaElement[union
333: .size()]);
334: }
335:
336: public static IResource[] union(IResource[] set1, IResource[] set2) {
337: List union = new ArrayList(set1.length + set2.length);//use lists to avoid sequence problems
338: addAll(ReorgUtils.getNotNulls(set1), union);
339: addAll(ReorgUtils.getNotNulls(set2), union);
340: return (IResource[]) union.toArray(new IResource[union.size()]);
341: }
342:
343: private static void addAll(Object[] array, List list) {
344: for (int i = 0; i < array.length; i++) {
345: if (!list.contains(array[i]))
346: list.add(array[i]);
347: }
348: }
349:
350: public static Set union(Set set1, Set set2) {
351: Set union = new HashSet(set1.size() + set2.size());
352: union.addAll(set1);
353: union.addAll(set2);
354: return union;
355: }
356:
357: public static IType[] getMainTypes(IJavaElement[] javaElements)
358: throws JavaModelException {
359: List result = new ArrayList();
360: for (int i = 0; i < javaElements.length; i++) {
361: IJavaElement element = javaElements[i];
362: if (element instanceof IType
363: && JavaElementUtil.isMainType((IType) element))
364: result.add(element);
365: }
366: return (IType[]) result.toArray(new IType[result.size()]);
367: }
368:
369: public static IFolder[] getFolders(IResource[] resources) {
370: Set result = getResourcesOfType(resources, IResource.FOLDER);
371: return (IFolder[]) result.toArray(new IFolder[result.size()]);
372: }
373:
374: public static IFile[] getFiles(IResource[] resources) {
375: Set result = getResourcesOfType(resources, IResource.FILE);
376: return (IFile[]) result.toArray(new IFile[result.size()]);
377: }
378:
379: //the result can be cast down to the requested type array
380: public static Set getResourcesOfType(IResource[] resources,
381: int typeMask) {
382: Set result = new HashSet(resources.length);
383: for (int i = 0; i < resources.length; i++) {
384: if (isOfType(resources[i], typeMask))
385: result.add(resources[i]);
386: }
387: return result;
388: }
389:
390: //the result can be cast down to the requested type array
391: //type is _not_ a mask
392: public static List getElementsOfType(IJavaElement[] javaElements,
393: int type) {
394: List result = new ArrayList(javaElements.length);
395: for (int i = 0; i < javaElements.length; i++) {
396: if (isOfType(javaElements[i], type))
397: result.add(javaElements[i]);
398: }
399: return result;
400: }
401:
402: public static boolean hasElementsNotOfType(IResource[] resources,
403: int typeMask) {
404: for (int i = 0; i < resources.length; i++) {
405: IResource resource = resources[i];
406: if (resource != null && !isOfType(resource, typeMask))
407: return true;
408: }
409: return false;
410: }
411:
412: //type is _not_ a mask
413: public static boolean hasElementsNotOfType(
414: IJavaElement[] javaElements, int type) {
415: for (int i = 0; i < javaElements.length; i++) {
416: IJavaElement element = javaElements[i];
417: if (element != null && !isOfType(element, type))
418: return true;
419: }
420: return false;
421: }
422:
423: //type is _not_ a mask
424: public static boolean hasElementsOfType(
425: IJavaElement[] javaElements, int type) {
426: for (int i = 0; i < javaElements.length; i++) {
427: IJavaElement element = javaElements[i];
428: if (element != null && isOfType(element, type))
429: return true;
430: }
431: return false;
432: }
433:
434: public static boolean hasElementsOfType(
435: IJavaElement[] javaElements, int[] types) {
436: for (int i = 0; i < types.length; i++) {
437: if (hasElementsOfType(javaElements, types[i]))
438: return true;
439: }
440: return false;
441: }
442:
443: public static boolean hasOnlyElementsOfType(
444: IJavaElement[] javaElements, int[] types) {
445: for (int i = 0; i < javaElements.length; i++) {
446: IJavaElement element = javaElements[i];
447: boolean found = false;
448: for (int j = 0; j < types.length && !found; j++) {
449: if (isOfType(element, types[j]))
450: found = true;
451: }
452: if (!found)
453: return false;
454: }
455:
456: return true;
457: }
458:
459: public static boolean hasElementsOfType(IResource[] resources,
460: int typeMask) {
461: for (int i = 0; i < resources.length; i++) {
462: IResource resource = resources[i];
463: if (resource != null && isOfType(resource, typeMask))
464: return true;
465: }
466: return false;
467: }
468:
469: private static boolean isOfType(IJavaElement element, int type) {
470: return element.getElementType() == type;//this is _not_ a mask
471: }
472:
473: private static boolean isOfType(IResource resource, int type) {
474: return resource != null && isFlagSet(resource.getType(), type);
475: }
476:
477: private static boolean isFlagSet(int flags, int flag) {
478: return (flags & flag) != 0;
479: }
480:
481: public static boolean isSourceFolder(IJavaElement javaElement)
482: throws JavaModelException {
483: return (javaElement instanceof IPackageFragmentRoot)
484: && ((IPackageFragmentRoot) javaElement).getKind() == IPackageFragmentRoot.K_SOURCE;
485: }
486:
487: public static boolean isClassFolder(IJavaElement javaElement)
488: throws JavaModelException {
489: return (javaElement instanceof IPackageFragmentRoot)
490: && ((IPackageFragmentRoot) javaElement).getKind() == IPackageFragmentRoot.K_BINARY;
491: }
492:
493: public static boolean isPackageFragmentRoot(IJavaProject javaProject)
494: throws JavaModelException {
495: return getCorrespondingPackageFragmentRoot(javaProject) != null;
496: }
497:
498: private static boolean isPackageFragmentRootCorrespondingToProject(
499: IPackageFragmentRoot root) {
500: return root.getResource() instanceof IProject;
501: }
502:
503: public static IPackageFragmentRoot getCorrespondingPackageFragmentRoot(
504: IJavaProject p) throws JavaModelException {
505: IPackageFragmentRoot[] roots = p.getPackageFragmentRoots();
506: for (int i = 0; i < roots.length; i++) {
507: if (isPackageFragmentRootCorrespondingToProject(roots[i]))
508: return roots[i];
509: }
510: return null;
511: }
512:
513: public static boolean containsLinkedResources(IResource[] resources) {
514: for (int i = 0; i < resources.length; i++) {
515: if (resources[i] != null && resources[i].isLinked())
516: return true;
517: }
518: return false;
519: }
520:
521: public static boolean containsLinkedResources(
522: IJavaElement[] javaElements) {
523: for (int i = 0; i < javaElements.length; i++) {
524: IResource res = getResource(javaElements[i]);
525: if (res != null && res.isLinked())
526: return true;
527: }
528: return false;
529: }
530:
531: public static boolean canBeDestinationForLinkedResources(
532: IResource resource) {
533: return resource.isAccessible() && resource instanceof IProject;
534: }
535:
536: public static boolean canBeDestinationForLinkedResources(
537: IJavaElement javaElement) {
538: if (javaElement instanceof IPackageFragmentRoot) {
539: return isPackageFragmentRootCorrespondingToProject((IPackageFragmentRoot) javaElement);
540: } else if (javaElement instanceof IJavaProject) {
541: return true;//XXX ???
542: } else
543: return false;
544: }
545:
546: public static boolean isParentInWorkspaceOrOnDisk(
547: IPackageFragment pack, IPackageFragmentRoot root) {
548: if (pack == null)
549: return false;
550: IJavaElement packParent = pack.getParent();
551: if (packParent == null)
552: return false;
553: if (packParent.equals(root))
554: return true;
555: IResource packageResource = ResourceUtil.getResource(pack);
556: IResource packageRootResource = ResourceUtil.getResource(root);
557: return isParentInWorkspaceOrOnDisk(packageResource,
558: packageRootResource);
559: }
560:
561: public static boolean isParentInWorkspaceOrOnDisk(
562: IPackageFragmentRoot root, IJavaProject javaProject) {
563: if (root == null)
564: return false;
565: IJavaElement rootParent = root.getParent();
566: if (rootParent == null)
567: return false;
568: if (rootParent.equals(root))
569: return true;
570: IResource packageResource = ResourceUtil.getResource(root);
571: IResource packageRootResource = ResourceUtil
572: .getResource(javaProject);
573: return isParentInWorkspaceOrOnDisk(packageResource,
574: packageRootResource);
575: }
576:
577: public static boolean isParentInWorkspaceOrOnDisk(
578: ICompilationUnit cu, IPackageFragment dest) {
579: if (cu == null)
580: return false;
581: IJavaElement cuParent = cu.getParent();
582: if (cuParent == null)
583: return false;
584: if (cuParent.equals(dest))
585: return true;
586: IResource cuResource = cu.getResource();
587: IResource packageResource = ResourceUtil.getResource(dest);
588: return isParentInWorkspaceOrOnDisk(cuResource, packageResource);
589: }
590:
591: public static boolean isParentInWorkspaceOrOnDisk(IResource res,
592: IResource maybeParent) {
593: if (res == null)
594: return false;
595: return areEqualInWorkspaceOrOnDisk(res.getParent(), maybeParent);
596: }
597:
598: public static boolean areEqualInWorkspaceOrOnDisk(IResource r1,
599: IResource r2) {
600: if (r1 == null || r2 == null)
601: return false;
602: if (r1.equals(r2))
603: return true;
604: URI r1Location = r1.getLocationURI();
605: URI r2Location = r2.getLocationURI();
606: if (r1Location == null || r2Location == null)
607: return false;
608: return r1Location.equals(r2Location);
609: }
610:
611: public static IResource[] getNotNulls(IResource[] resources) {
612: Collection result = new ArrayList(resources.length);
613: for (int i = 0; i < resources.length; i++) {
614: IResource resource = resources[i];
615: if (resource != null && !result.contains(resource))
616: result.add(resource);
617: }
618: return (IResource[]) result
619: .toArray(new IResource[result.size()]);
620: }
621:
622: public static IResource[] getNotLinked(IResource[] resources) {
623: Collection result = new ArrayList(resources.length);
624: for (int i = 0; i < resources.length; i++) {
625: IResource resource = resources[i];
626: if (resource != null && !result.contains(resource)
627: && !resource.isLinked())
628: result.add(resource);
629: }
630: return (IResource[]) result
631: .toArray(new IResource[result.size()]);
632: }
633:
634: /* List<IJavaElement> javaElements
635: * return ICompilationUnit -> List<IJavaElement>
636: */
637: public static Map groupByCompilationUnit(List javaElements) {
638: Map result = new HashMap();
639: for (Iterator iter = javaElements.iterator(); iter.hasNext();) {
640: IJavaElement element = (IJavaElement) iter.next();
641: ICompilationUnit cu = ReorgUtils
642: .getCompilationUnit(element);
643: if (cu != null) {
644: if (!result.containsKey(cu))
645: result.put(cu, new ArrayList(1));
646: ((List) result.get(cu)).add(element);
647: }
648: }
649: return result;
650: }
651:
652: public static void splitIntoJavaElementsAndResources(
653: Object[] elements, List javaElementResult,
654: List resourceResult) {
655: for (int i = 0; i < elements.length; i++) {
656: Object element = elements[i];
657: if (element instanceof IJavaElement) {
658: javaElementResult.add(element);
659: } else if (element instanceof IResource) {
660: IResource resource = (IResource) element;
661: IJavaElement jElement = JavaCore.create(resource);
662: if (jElement != null && jElement.exists())
663: javaElementResult.add(jElement);
664: else
665: resourceResult.add(resource);
666: }
667: }
668: }
669:
670: public static boolean containsElementOrParent(Set elements,
671: IJavaElement element) {
672: IJavaElement curr = element;
673: do {
674: if (elements.contains(curr))
675: return true;
676: curr = curr.getParent();
677: } while (curr != null);
678: return false;
679: }
680:
681: public static boolean containsElementOrParent(Set elements,
682: IResource element) {
683: IResource curr = element;
684: do {
685: if (elements.contains(curr))
686: return true;
687: IJavaElement jElement = JavaCore.create(curr);
688: if (jElement != null && jElement.exists()) {
689: return containsElementOrParent(elements, jElement);
690: }
691: curr = curr.getParent();
692: } while (curr != null);
693: return false;
694: }
695: }
|