1 package no.uio.ifi.refaktor.extractors;
3 import java.util.Collections;
4 import java.util.Comparator;
5 import java.util.LinkedList;
7 import no.uio.ifi.refaktor.changers.ExtractAndMoveMethodChanger;
8 import no.uio.ifi.refaktor.changers.RefaktorChangerException;
9 import no.uio.ifi.refaktor.changers.RefaktorChangerException.Reason;
10 import no.uio.ifi.refaktor.extractors.collectors.PrefixesCollector;
11 import no.uio.ifi.refaktor.extractors.collectors.SelectionChecker;
12 import no.uio.ifi.refaktor.extractors.collectors.UnfixesCollector;
13 import no.uio.ifi.refaktor.prefix.Prefix;
14 import no.uio.ifi.refaktor.prefix.PrefixSet;
15 import no.uio.ifi.refaktor.utils.CompilationUnitTextSelection;
18 * A property extractor that collects all the expression prefixes within a selection
19 * (see {@link PrefixesCollector}) that forms the base for calculating the
20 * candidates for the move refactoring, and also the unfixes
21 * that are non-candidates for the move refactoring.
23 * The set of prefixes that are not enclosing any unfixes is put in the set of safe prefixes.
24 * This set is used by an Extract and Move Method refactoring to find a suitable target
25 * for the Move Method.
27 * The class is typically used by the {@link ExtractAndMoveMethodChanger}.
29 public class ExtractAndMoveMethodPrefixesExtractor implements PropertiesExtractor {
31 private final CompilationUnitTextSelection selection;
32 private final PrefixesCollector prefixesCollector;
33 private final UnfixesCollector unfixesCollector;
34 private PrefixSet safePrefixes = null;
36 public ExtractAndMoveMethodPrefixesExtractor(CompilationUnitTextSelection selection) {
37 this.selection = selection;
38 prefixesCollector = new PrefixesCollector(selection);
39 unfixesCollector = new UnfixesCollector(selection);
42 public PrefixSet getSafePrefixes() {
43 if (safePrefixes == null) {
44 safePrefixes = createSafePrefixes();
49 private PrefixSet createSafePrefixes() {
50 return prefixesCollector.getPrefixes().minusEnclosedPrefixesFrom(unfixesCollector.getUnfixes());
53 public boolean hasUsefulResults() {
54 return !getSafePrefixes().isEmpty();
57 protected PrefixSet getPrefixes() {
58 return prefixesCollector.getPrefixes();
61 protected PrefixSet getUnfixes() {
62 return unfixesCollector.getUnfixes();
65 public Prefix getMostFrequentPrefix() {
66 LinkedList<Prefix> listOfSafePrefixes = getListOfSafePrefixes();
67 sortAscendingByCountAndLength(listOfSafePrefixes);
68 return listOfSafePrefixes.getLast();
71 private LinkedList<Prefix> getListOfSafePrefixes() {
72 return getSafePrefixes().toList();
75 private void sortAscendingByCountAndLength(LinkedList<Prefix> values) {
76 Collections.sort(values, new Comparator<Prefix>() {
78 public int compare(Prefix p1, Prefix p2) {
79 if (p1.getCount() > p2.getCount()) {
81 } else if (p1.getCount() < p2.getCount()) {
83 } else if (p1.length() > p2.length()) {
85 } else if (p1.length() < p2.length()) {
93 public void checkPreconditions() throws RefaktorChangerException {
94 checkIfSelectionIsValid();
96 checkIfUsefulTargetFound();
99 public void checkIfSelectionIsValid() {
100 if (!selectionIsValid())
101 throw new RefaktorChangerException(Reason.SELECTION_INVALID);
104 private void checkIfUsefulTargetFound() {
105 if (!hasUsefulResults())
106 throw new RefaktorChangerException(Reason.NO_TARGET_FOUND);
110 public void extractProperties() {
111 CollectorManager.collectProperties(selection, prefixesCollector, unfixesCollector);
114 private boolean selectionIsValid() {
115 return SelectionChecker.isSelectionValid(selection);