package br.uff.ic.gems.peixeespadacliente.tool; import br.uff.ic.gems.peixeespadacliente.exception.RefactoringException; import br.uff.ic.gems.peixeespadacliente.model.ProjectVCS; import br.uff.ic.gems.peixeespadacliente.resolution.ExtractInterfaceResolution; import br.uff.ic.gems.peixeespadacliente.resolution.Resolution; import br.uff.ic.gems.peixeespadacliente.symptom.ExtractInterfaceSymptom; import br.uff.ic.gems.peixeespadacliente.symptom.Symptom; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import net.sf.refactorit.classmodel.BinCIType; import net.sf.refactorit.classmodel.BinCITypeRef; import net.sf.refactorit.classmodel.BinField; import net.sf.refactorit.classmodel.BinMember; import net.sf.refactorit.classmodel.BinTypeRef; import net.sf.refactorit.commonIDE.IDEController; import net.sf.refactorit.refactorings.RefactoringStatus; import net.sf.refactorit.refactorings.extractsuper.ExtractSuper; import net.sf.refactorit.refactorings.usesupertype.UseSuperTypeRefactoring; import net.sf.refactorit.test.refactorings.NullContext; import translation.Translate; /** * * @author João Felipe */ public class ExtractInterfaces extends AbstractRefactoringTool { private ExtractSuper extractor = null; private BinTypeRef currentClassRef = null; private BinCIType currentClass = null; public ExtractInterfaces(ProjectVCS projectVCS) { super(projectVCS); } public boolean reloadRefactoring() { try { extractor = new ExtractSuper(new NullContext(getProject()), currentClassRef); extractor.setNewPackageName(currentClass.getPackage().getQualifiedName()); List<BinMember> extractableMembers = interfaceExtractableMembers(currentClass); List membersToExtract = new ArrayList(); Set abstractMethods = new HashSet(); for (BinMember binMember : extractableMembers) { membersToExtract.add(binMember); abstractMethods.add(binMember); } this.extractor.setMembersToExtract(membersToExtract); this.extractor.setExplicitlyAbstractMethods(abstractMethods); return true; } catch (NullPointerException e) { return false; } } @Override public boolean prepareSymptom(Symptom symptom) throws RefactoringException { loadEnvironment(); // reloadEnv(); ExtractInterfaceSymptom extractInterfaceSymptom = (ExtractInterfaceSymptom) symptom; currentClassRef = getProject().getTypeRefForSourceName(extractInterfaceSymptom.getClassQualifiedName()); currentClass = currentClassRef.getBinCIType(); return reloadRefactoring(); } private List<BinMember> interfaceExtractableMembers(BinCIType bcitr) { List<BinMember> result = new ArrayList<BinMember>(); List members = new ArrayList(); members.addAll(Arrays.asList(bcitr.getDeclaredFields())); members.addAll(Arrays.asList(bcitr.getDeclaredMethods())); // searching for at least one member satisfying our conditions for (int i = 0, max = members.size(); i < max; i++) { final BinMember member = (BinMember) members.get(i); // members must be public if (!member.isPublic()) { continue; } // fields should be public static final if (member instanceof BinField) { if (!member.isFinal() || !member.isStatic()) { continue; } } // result.add(member); } return result; } @Override public List<Symptom> findAllSymptoms() throws RefactoringException { if (!loadEnvironment()) { return null; } List<Symptom> result = new ArrayList<Symptom>(); for (Object object : getProject().getDefinedTypes()) { BinCITypeRef binCITypeRef = (BinCITypeRef) object; BinCIType bcitr = binCITypeRef.getBinCIType(); if (bcitr.isInterface()) { continue; } if (interfaceExtractableMembers(bcitr).isEmpty()) { continue; } Symptom symptom = new ExtractInterfaceSymptom(bcitr, this); result.add(symptom); } return result; } @Override public boolean applyCheckingPreAndPosCondictions(Resolution resolution) throws RefactoringException { Translate translate = Translate.getTranslate(); ExtractInterfaceResolution eiResolution = (ExtractInterfaceResolution) resolution; extractor.setNewTypeName(eiResolution.getNewTypeName()); extractor.setExtractClass(eiResolution.getExtractClass()); extractor.setForceExtractMethodsAbstract(eiResolution.getForceExtractMethodsAbstract()); extractor.setExtractWithOldName(eiResolution.getExtractWithOldName()); refactoring = extractor; RefactoringStatus status = checkPreconditions(); if (status.isErrorOrFatal()) { throw new RefactoringException(translate.notRefactored(status.getAllMessages())); } status.merge(checkUserInput()); status.merge(extractor.apply()); if (!status.isOk()) { throw new RefactoringException(translate.error(status.getAllMessages())); } System.out.println(status.getAllMessages()); return !status.isErrorOrFatal() && useSuperTypeWhereIsPossible(status); // return !status.isErrorOrFatal(); /* Talvez usar o método useSuperTypeWhereIsPossible dificulte a aplicação com sucesso */ } public boolean useSuperTypeWhereIsPossible(RefactoringStatus status) { loadEnvironment(); // context.rebuildAndUpdateEnvironment(); String supertypeName = extractor.getSupertypeQualifiedName(); String subtypeName = extractor.getSubtypeQualifiedName(); BinTypeRef subtypeRef = getProject().findTypeRefForName(subtypeName); BinTypeRef supertypeRef = getProject().findTypeRefForName(supertypeName); if (subtypeRef == null) { //DialogManager.getInstance().showCustomError(context, "Type " + subtypeName + " not found after rebuild"); return false; } if (supertypeRef == null) { //DialogManager.getInstance().showCustomError(context, "Type " + supertypeName + " not found after rebuild"); return false; } final UseSuperTypeRefactoring ust = new UseSuperTypeRefactoring( supertypeRef.getBinCIType(), IDEController.getInstance().createProjectContext()){ @Override public String getDescription() { return extractor.getDescription() + " and use it where possible"; } @Override public String getName(){ return extractor.getName(); } }; ust.getTransformationManager().getEditorManager().setPersistantLineManager(true); ust.setSupertype(supertypeRef); ust.setSubtypes(Collections.singletonList(subtypeRef)); ust.setUseInstanceOf(false); status.addEntry(ust.checkPreconditions()); status.addEntry(ust.checkUserInput()); if (status != null && status.isOk()){ // FIXME: temporary solution to RIM-765 just to make RIT stable /*LineManager lineManager = extractor.getTransformationManager() .getEditorManager().getLineManager(); lineManager.remapSources(context); ust.getTransformationManager().getEditorManager().setLineManager( lineManager);*/ status.addEntry(ust.apply()); } return status != null && status.isOk(); } }