diff --git a/src/org/ntlab/pushPullRefactoring/Measurement.java b/src/org/ntlab/pushPullRefactoring/Measurement.java new file mode 100644 index 0000000..93e4555 --- /dev/null +++ b/src/org/ntlab/pushPullRefactoring/Measurement.java @@ -0,0 +1,16 @@ +package org.ntlab.pushPullRefactoring; + +public class Measurement { + static long start; + static long end; + public static void start() { + start = System.nanoTime(); + } + public static void endTime() { + end = System.nanoTime(); + long t = end - start; + System.out.println("time : " + t ); + } + + +} diff --git a/src/org/ntlab/pushPullRefactoring/PushPullDescriptor.java b/src/org/ntlab/pushPullRefactoring/PushPullDescriptor.java index fd8b275..520ab3b 100644 --- a/src/org/ntlab/pushPullRefactoring/PushPullDescriptor.java +++ b/src/org/ntlab/pushPullRefactoring/PushPullDescriptor.java @@ -1,7 +1,10 @@ package org.ntlab.pushPullRefactoring; import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; public class PushPullDescriptor extends JavaRefactoringDescriptor { @@ -12,7 +15,16 @@ private CompilationUnit distinationClass = null; private boolean isPushToPull; + + public boolean isPushToPull() { + return isPushToPull; + } + + public void setPushToPull(boolean isPushToPull) { + this.isPushToPull = isPushToPull; + } + protected PushPullDescriptor() { super(PushPullRefactoring.ID); } @@ -23,6 +35,13 @@ public void setSourceClass(CompilationUnit sourceClass) { this.sourceClass = sourceClass; + sourceClass.accept(new ASTVisitor() { + @Override + public boolean visit(TypeDeclaration node) { + sourceClassName = node.getName().toString(); + return false; + } + }); } public CompilationUnit getDistinationClass() { @@ -31,15 +50,20 @@ public void setDistinationClass(CompilationUnit distinationClass) { this.distinationClass = distinationClass; + distinationClass.accept(new ASTVisitor() { + @Override + public boolean visit(TypeDeclaration node) { + distinationClassName = node.getName().toString(); + return false; + } + }); + } public String getDistinationClassName() { return distinationClassName; } - - public void setDistinationClassName(String distinationClassName) { - this.distinationClassName = distinationClassName; + public String getSourceClassName() { + return sourceClassName; } - - } diff --git a/src/org/ntlab/pushPullRefactoring/PushPullProcessor.java b/src/org/ntlab/pushPullRefactoring/PushPullProcessor.java index de1af18..14a2c76 100644 --- a/src/org/ntlab/pushPullRefactoring/PushPullProcessor.java +++ b/src/org/ntlab/pushPullRefactoring/PushPullProcessor.java @@ -1,7 +1,15 @@ package org.ntlab.pushPullRefactoring; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.stream.Collectors; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filebuffers.ITextFileBuffer; @@ -24,16 +32,44 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.Annotation; +import org.eclipse.jdt.core.dom.ArrayInitializer; +import org.eclipse.jdt.core.dom.Assignment; +import org.eclipse.jdt.core.dom.Block; +import org.eclipse.jdt.core.dom.BodyDeclaration; +import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionStatement; +import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.InfixExpression; +import org.eclipse.jdt.core.dom.MarkerAnnotation; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.NormalAnnotation; +import org.eclipse.jdt.core.dom.PackageDeclaration; +import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.PrimitiveType; +import org.eclipse.jdt.core.dom.ReturnStatement; +import org.eclipse.jdt.core.dom.SingleMemberAnnotation; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; +import org.eclipse.jdt.core.dom.rewrite.ListRewrite; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; @@ -47,6 +83,8 @@ import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange; import org.eclipse.jdt.internal.corext.refactoring.changes.RenameCompilationUnitChange; +import org.eclipse.jdt.ui.CodeStyleConfiguration; +import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.ltk.core.refactoring.Change; @@ -55,18 +93,31 @@ import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; +import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.TextEdit; +import org.eclipse.text.edits.TextEditGroup; +import org.eclipse.text.edits.UndoEdit; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.editors.text.FileDocumentProvider; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IDocumentProviderExtension; public class PushPullProcessor extends RefactoringProcessor { private PushPullDescriptor descriptor = null; + public PushPullProcessor(PushPullDescriptor descriptor) { this.descriptor = descriptor; } - + @Override public Object[] getElements() { // TODO Auto-generated method stub @@ -105,194 +156,892 @@ return null; } - //���̒��ŕύX���e���쐬���� + // ���̒��ŕύX���e���쐬���� @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { - DynamicValidationRefactoringChange result = new DynamicValidationRefactoringChange(descriptor, PushPullRefactoring.NAME); - ICompilationUnit[] icus = new ICompilationUnit[1]; - //createPushPullChanges(); - FieldDeclaration fieldDec = searchFieldDeclaration("State"); -// ASTParser parser = ASTParser.newParser(AST.JLS4); -// parser.setKind(ASTParser.K_COMPILATION_UNIT); -// parser.setResolveBindings(true); -// parser.setBindingsRecovery(true); -// parser.setSource(.getTypeRoot()); - String code=""; - try { - String initialContent = descriptor.getDistinationClass().getTypeRoot().getSource(); - // �ϊ����ʂ𕶎���Ŏ擾 - code = getCode(initialContent, descriptor.getDistinationClass()); - } catch (JavaModelException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - System.out.println(code); - //System.out.println(code); - //IWorkspace w = ResourcesPlugin.getWorkspace(); - //w.getRoot().accept(visitor, IContainer.DEPTH_INFINITE, false); + DynamicValidationRefactoringChange result = new DynamicValidationRefactoringChange(descriptor, + PushPullRefactoring.NAME); + ICompilationUnit[] icus = new ICompilationUnit[1]; -// SearchPattern pattern = createSearchPattern(); -// SearchParticipant[] participants = { SearchEngine.getDefaultSearchParticipant() }; -// -// IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); -//// IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject }); -// //��������v�����m�[�h�ɑ΂��čs���ύX -// SearchRequestor requestor = new SearchRequestor() { -// @Override -// public void acceptSearchMatch(SearchMatch match) throws CoreException { -// IJavaElement element = (IJavaElement) match.getElement(); -// -// System.out.println(element.getElementType()); -// ICompilationUnit icu = ((SourceType) element).getCompilationUnit(); -// System.out.println("name:" + icu.getElementName()); -// if (icu.getElementName().equals("A.java")) { -// icus[0] = icu; -// } -// -// System.out.printf("%s %d,%d\n", element.getElementName(), match.getOffset(), match.getLength()); -// } -// }; - -// try { -// new SearchEngine().search(pattern, participants, scope, requestor, new NullProgressMonitor()); -// } catch (CoreException e) { -// e.printStackTrace(); -// } - if (icus[0] != null) { - //result.add(new RenameCompilationUnitChange(icus[0], "hogehoge")); + if (descriptor.isPushToPull()) { + changePush2Pull(pm); + } else { + changePull2Push(pm); } - + Measurement.endTime(); return result; } - private Change createPushPullChanges() { - // TODO Auto-generated method stub - SearchPattern pattern = createSearchPattern(); - SearchParticipant[] participants = { SearchEngine.getDefaultSearchParticipant() }; - IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); - return null; - } - private ASTNode searchFieldNode(String annotationName,String... value) { - ASTNode[] result = new ASTNode[1]; - final String a = "@"+annotationName; + private void changePush2Pull(IProgressMonitor pm) { + var srcUnit = descriptor.getSourceClass(); + var dstUnit = descriptor.getDistinationClass(); + var dstDec = new TypeDeclaration[1]; + var messages = searchMethodDeclarations(srcUnit, "Message"); + var md = searchMethodDeclaration(dstUnit, "Message", annotationValueCase(descriptor.getSourceClassName())); descriptor.getDistinationClass().accept(new ASTVisitor() { @Override + public boolean visit(TypeDeclaration node) { + dstDec[0] = node; + return false; + } + }); + ASTRewrite dstUnitRewrite = ASTRewrite.create(dstDec[0].getAST()); + //ASTRewrite dstUnitRewrite = ASTRewrite.create(dstUnit.getAST()); + + String srcValue = annotationValueCase(descriptor.getSourceClassName()); + String dstValue = annotationValueCase(descriptor.getDistinationClassName()); + String pullrefCode = "@PullReference(\"" + srcValue + "\")" + System.getProperty("line.separator") + "@Pushable" + + System.getProperty("line.separator") + "String " + srcValue + "= " + "\"/" + srcValue + "\";"; + // @PullReference���t�^���ꂽ�t�B�[���h��lj� + addStatement(dstUnitRewrite, dstUnit, dstDec[0], pullrefCode); + + String importPullRef = "import pushPullRefactor.PullReference;" + System.getProperty("line.separator") + + "import pushPullRefactor.Pushable;" + System.getProperty("line.separator") + + System.getProperty("line.separator") ; + addStatement(dstUnitRewrite, dstUnit, dstDec[0],importPullRef,TypeDeclaration.MODIFIERS2_PROPERTY); + + if(!hasClient(dstUnit)) { + addStatement(dstUnitRewrite, dstUnit, dstDec[0],"import javax.ws.rs.client.*;" + System.getProperty("line.separator"),TypeDeclaration.MODIFIERS2_PROPERTY); + addStatement(dstUnitRewrite, dstUnit, dstDec[0], "private Client client = ClientBuilder.newClient();"+ System.getProperty("line.separator")); + } + + // @State���t�^���ꂽ�t�B�[���h���폜 + deleteASTNode(dstUnitRewrite, dstUnit, searchFieldDeclaration(descriptor.getDistinationClass(), "State")); + + // @Message���t�^���ꂽ���\�b�h���폜 +// deleteASTNode(dstUnitRewrite, dstUnit, +// searchMethodDeclaration(dstUnit, "Message", annotationValueCase(descriptor.getSourceClassName()))); + deleteASTNode(dstUnitRewrite, dstUnit, + searchMethodDeclaration(dstUnit, "Message", annotationValueCase(descriptor.getSourceClassName()))); + // @Getter���t�^���ꂽ���\�b�h�̕Ԃ�l�����̏�Ōv�Z����悤�ɕύX + var srcState = searchFieldDeclaration(srcUnit, "State"); + Type srcType = srcState.getType(); + var getterStatements = generateGetStatement(srcValue, srcValue, srcType); + var transition = new Expression[1]; + md.accept(new ASTVisitor() { +// @Override +// public boolean visit(InfixExpression node) { +// var left = node.getLeftOperand(); +// +// transition[0] = node; +// return true; +// } + @Override + public boolean visit(Assignment node) { + var left = node.getLeftHandSide(); + if(left.toString().equals("this.value")); + transition[0] = node.getRightHandSide(); + return true; + } + }); + var getter = searchMethodDeclaration(dstUnit, "Getter"); + var returnStatement = new ReturnStatement[1]; + getter.accept(new ASTVisitor() { + @Override + public boolean visit(ReturnStatement node) { + returnStatement[0] = node; + return true; + } + }); + + addStatement(dstUnitRewrite, dstUnit, getter.getBody(), getterStatements, Block.STATEMENTS_PROPERTY); + replaceASTNode(dstUnitRewrite, dstUnit, returnStatement[0].getExpression(), transition[0]); + + var srcDec = new TypeDeclaration[1]; + descriptor.getSourceClass().accept(new ASTVisitor() { + @Override + public boolean visit(TypeDeclaration node) { + srcDec[0] = node; + return false; + } + }); + ASTRewrite srcUnitRewrite = ASTRewrite.create(srcDec[0].getAST()); + // �]�����̕ύX + deletePutMethodInvocation(srcUnitRewrite, srcUnit, dstValue); + // @PushReference���t�^���ꂽ�t�B�[���h���폜 + deleteASTNode(srcUnitRewrite, srcUnit, + searchFieldDeclaration(descriptor.getSourceClass(), "PushReference", dstValue)); + + System.out.println(dstUnitRewrite.toString()); + try { + applyRewrite(srcUnit, srcUnitRewrite, pm); + applyRewrite(dstUnit, dstUnitRewrite, pm); + + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + } + private void addImport(CompilationUnit cu, String importString, IProgressMonitor pm) throws Exception { + ImportRewrite importRewrite = CodeStyleConfiguration.createImportRewrite(cu, true); + AST ast = cu.getAST(); + Type rtype = ast.newSimpleType(ast.newName(importRewrite.addImport(importString))); + TextEdit importEdit = importRewrite.rewriteImports(null); + IPath path = cu.getJavaElement().getPath(); + ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager(); + bufferManager.connect(path, LocationKind.IFILE, pm); + ITextFileBuffer textFileBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE); + IDocument document = textFileBuffer.getDocument(); + importEdit.apply(document); + } + private boolean hasClient(ASTNode astNode) { + boolean[] result = {false} ; + astNode.accept(new ASTVisitor() { public boolean visit(FieldDeclaration node) { - var modifiers = node.modifiers(); - for(var annotation : modifiers) { - String annoName = annotation.toString(); - if(a.equals(annoName)) { - var r = node; - // result[0] = (SourceField)node; - List fragments = node.fragments(); - VariableDeclarationFragment fragment = fragments.get(0); - //IJavaElement fieldElement = fragment.resolveBinding().getJavaElement(); - result[0] = fragments.get(0); - } + if(node.getType().toString().equals("Client")) { + + result[0] = true; } return false; } - }); return result[0]; } - private FieldDeclaration searchFieldDeclaration(String annotationName,String... value) { - FieldDeclaration[] result = new FieldDeclaration[1]; - final String a = "@"+annotationName; + private void applyRewrite(CompilationUnit unit, ASTRewrite unitRewrite, IProgressMonitor pm) throws Exception { + IPath path = unit.getJavaElement().getPath(); + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IFile file = workspaceRoot.getFile(path); +// if(isOpened(file)) { +// IWorkbench workbench = PlatformUI.getWorkbench(); +// IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); +// IWorkbenchPage page = window.getActivePage(); +// IEditorPart editor = IDE.openEditor(page, file); +// } + ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager(); + bufferManager.connect(path, LocationKind.IFILE, pm); + ITextFileBuffer textFileBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE); + IDocument document = textFileBuffer.getDocument(); + TextEdit edit = unitRewrite.rewriteAST(document, null); + UndoEdit undo = edit.apply(document); + textFileBuffer.commit(null /* ProgressMonitor */, true/* Overwrite */); - descriptor.getDistinationClass().accept(new ASTVisitor() { - @Override - public boolean visit(FieldDeclaration node) { - var modifiers = node.modifiers(); - for(var annotation : modifiers) { - String annoName = annotation.toString(); - if(a.equals(annoName)) { - var r = node; - // result[0] = (SourceField)node; - List fragments = node.fragments(); - VariableDeclarationFragment fragment = fragments.get(0); - //IJavaElement fieldElement = fragment.resolveBinding().getJavaElement(); - node.delete(); - System.out.println("Deleted"); + } + + private boolean isOpened(IFile targetFile) { + IEditorInput input = new FileEditorInput(targetFile); + IWorkbench workbench = PlatformUI.getWorkbench(); + IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + for (int i = 0; i < windows.length; i++) { + IWorkbenchPage[] pages = windows[i].getPages(); + for (int j = 0; j < pages.length; j++) { + IEditorPart editor = pages[j].findEditor(input); + if (editor != null) { + // �G�f�B�^�ŊJ����Ă��� + return true; + } + } + } + // �G�f�B�^�ŊJ����Ă��Ȃ� + return false; + } + + private void deletePutMethodInvocation(ASTRewrite astRewrite, CompilationUnit srcUnit, String resourceName) { + var updateMethods = searchMethodDeclarations(srcUnit, "Message"); + for (MethodDeclaration md : updateMethods) { + LinkedHashMap> invocations = getPutMethodInvocations(md); + System.out.println(invocations); + // ���\�b�h�̌Ăяo���Q��2�ˆȏ�ł���, + // invocations����Ή����\�[�X�ւ̃��\�b�h�Ăяo���Q��, + // invocations�̐擪�ɂ��郁�\�b�h�Ăяo���Q����v���邩�𔻒� + Iterator>> invocationsIterator = invocations.entrySet().iterator(); + var g = invocations.get(resourceName); + var i = (invocationsIterator.next()).getKey().equals(resourceName); + if (invocations.size() > 1 && i) { + + for (Statement st : (List) invocationsIterator.next().getValue()) { + ASTNode[] n = new ASTNode[1]; + st.accept(new ASTVisitor() { + @Override + public boolean visit(Assignment node) { + if (node.getLeftHandSide().toString().equals("form")) { + n[0] = node; + addDecStatement(node, "Form "); + } + if (node.getLeftHandSide().toString().equals("entity")) { + n[0] = node; + addDecStatement(node, "Entity
"); + } + if (node.getLeftHandSide().toString().equals("result")) { + MethodInvocation right = (MethodInvocation) node.getRightHandSide(); + n[0] = node; + addDecStatement(node, "String "); + } + return super.visit(node); + } + + public void addDecStatement(Assignment node, String typeName) { + // addStatement(astRewrite, srcUnit, node, typeName, Assignment ); + addStatementBefore(astRewrite, srcUnit, md.getBody(), node.getParent(), typeName, + Block.STATEMENTS_PROPERTY); + } + }); + + } + } + + for (Statement st : invocations.get(resourceName)) { + deleteASTNode(astRewrite, srcUnit, st); + } + + } + + } + + /** + * �����Ƃ��ēn���ꂽMethodDeclaration�̃��\�b�h�{�f�B���ɂ���PUT���\�b�h�̌Ăяo�����擾���郁�\�b�h + * + * @param md + * @return + */ + private LinkedHashMap> getPutMethodInvocations(MethodDeclaration md) { + LinkedHashMap> invocations = new LinkedHashMap<>(); + List statements = new ArrayList<>(); + + boolean[] isRegistering = new boolean[1]; + for (var st : md.getBody().statements()) { + Statement statement = (Statement) st; + + statement.accept(new ASTVisitor() { + + @Override + public boolean visit(VariableDeclarationStatement node) { + if (node.getType().toString().equals("Form")) { + startRegister(); } + if (node.getType().toString().equals("String")) { + if (((VariableDeclarationFragment) node.fragments().get(0)).getName().toString() + .equals("result")) { + + MethodInvocation right = (MethodInvocation) ((VariableDeclarationFragment) node.fragments() + .get(0)).getInitializer(); + String resourceName = ((MethodInvocation) ((MethodInvocation) right.getExpression()) + .getExpression()).arguments().get(0).toString(); + stopRegister(resourceName); + } + } + return super.visit(node); + } + + @Override + public boolean visit(Assignment node) { + if (node.getLeftHandSide().toString().equals("form")) { + startRegister(); + } + if (node.getLeftHandSide().toString().equals("result")) { + MethodInvocation right = (MethodInvocation) node.getRightHandSide(); + String resourceName = ((MethodInvocation) ((MethodInvocation) right.getExpression()) + .getExpression()).arguments().get(0).toString(); + stopRegister(resourceName); + } + return super.visit(node); + } + + private void startRegister() { + isRegistering[0] = true; + + statements.clear(); + } + + private void stopRegister(String resourceName) { + statements.add(statement); + invocations.put(resourceName, List.copyOf(statements)); + isRegistering[0] = false; + } + }); + if (isRegistering[0]) { + statements.add(statement); + } + } + return invocations; + } + + public MethodDeclaration[] searchMethodDeclarations(CompilationUnit cu, String annotationName, String... values) { + List result = new ArrayList(); + cu.accept(new ASTVisitor() { + @Override + public boolean visit(MethodDeclaration node) { + if (hasMatchAnnotation(node, node.modifiers(), annotationName, values)) { + result.add(node); } return super.visit(node); } + }); + return result.toArray(new MethodDeclaration[] {}); + } + + private String generateGetStatement(String assignedValue, String path, Type type) { + // �Ԃ��{�f�B�S�̂̃\�[�X�R�[�h + String result = ""; + // �]�����̒l��������ϐ��� + String tmp = assignedValue; + // GET���\�b�h�̈����œn���^�� + String simpleType = type.toString(); + if (type instanceof ParameterizedType) { + ParameterizedType ptype = (ParameterizedType) type; + if (ptype.getType().toString().equals("List")) { + simpleType = "ArrayList"; + tmp = assignedValue + "_json"; + + result += "List<" + convertType((Type) ptype.typeArguments().get(0)) + "> "; + result += tmp + " = client.target(\"http://localhost:8080\").path(this."+path+").request().get(" + + simpleType + ".class);" + System.getProperty("line.separator"); + + result += "List<" + ptype.typeArguments().get(0) + "> " + assignedValue + " = new ArrayList<>();" + + System.getProperty("line.separator"); + + result += geterateParameterizedTypeStatements(assignedValue, tmp, type); + } + if (ptype.getType().toString().equals("Map.Entry")) { + simpleType = "HashMap"; + tmp = assignedValue + "_json"; + result += convertType((Type) ptype) + " "; + result += tmp + " = client.target(\"http://localhost:8080\").path(this."+path+").request().get(" + + simpleType + ".class);" + System.getProperty("line.separator"); + + result += (Type) ptype + " " + assignedValue + " = new AbstractMap.SimpleEntry<>(" + tmp + + ".entrySet().iterator().next().getKey(), " + + geterateParameterizedTypeStatements(assignedValue, + tmp + ".entrySet().iterator().next().getValue()", (Type) ptype.typeArguments().get(1)) + + ");" + System.getProperty("line.separator"); + + // result += convertType((Type) ptype.typeArguments().get(0)); + + } + } + + return result; + } + + /** + * Map.Entry��Map�ɕϊ����郁�\�b�h + * + * @param type + * @return + */ + private String convertType(Type type) { + + if ((type instanceof ParameterizedType + && ((ParameterizedType) type).getType().toString().equals("Map.Entry"))) { + + return "Map"; + } + return type.toString(); + } + + private String geterateParameterizedTypeStatements(String value, String tmpValue, Type type) { + if (type instanceof ParameterizedType) { + ParameterizedType ptype = (ParameterizedType) type; + if (ptype.getType().toString().equals("List")) { + String str = "for (" + convertType((Type) ptype.typeArguments().get(0)) + " i: " + tmpValue + ") {" + + System.getProperty("line.separator"); + var argment = ((Type) ptype.typeArguments().get(0)); + str += value + ".add(" + geterateParameterizedTypeStatements(value, "i", argment) + ");"; + str += System.getProperty("line.separator") + "}"; + return str; + } + if (ptype.getType().toString().equals("Map.Entry")) { + String parsedKey = ""; + if (ptype.typeArguments().get(0).toString().equals("Integer")) { + parsedKey += ptype.typeArguments().get(0) + ".parseInt(" + tmpValue + + ".entrySet().iterator().next().getKey())"; + } else { + parsedKey += tmpValue + ".entrySet().iterator().next().getKey()"; + } + + String str = "new AbstractMap.SimpleEntry<>(" + parsedKey + ", " + tmpValue + + ".entrySet().iterator().next().getValue())"; + return str; + } + for (var arg : ((ParameterizedType) type).typeArguments()) { + + } + } + return ""; + } + + private void changePull2Push(IProgressMonitor pm) { + var srcUnit = descriptor.getSourceClass(); + var dstUnit = descriptor.getDistinationClass(); + var srcDec = new TypeDeclaration[1]; + var messages = searchMethodDeclarations(srcUnit, "Message"); + var md = searchMethodDeclaration(dstUnit, "Message", annotationValueCase(descriptor.getSourceClassName())); + descriptor.getSourceClass().accept(new ASTVisitor() { + @Override + public boolean visit(TypeDeclaration node) { + srcDec[0] = node; + return false; + } + }); + ASTRewrite srcUnitRewrite = ASTRewrite.create(srcDec[0].getAST()); + String srcValue = annotationValueCase(descriptor.getSourceClassName()); + String dstValue = annotationValueCase(descriptor.getDistinationClassName()); + + // @PushReference���t�^���ꂽ�t�B�[���h��lj� + String pushrefCode = "@PushReference(\"" + dstValue + "\")" + System.getProperty("line.separator") + "@Pullable(\"direct\")" + + System.getProperty("line.separator") + "String " + dstValue + "= " + "\"/" + dstValue + "\";"; + addStatement(srcUnitRewrite, srcUnit, srcDec[0], pushrefCode); + + String importPushRef = "import pushPullRefactor.PushReference;" + System.getProperty("line.separator") + + "import pushPullRefactor.Pullable;" + System.getProperty("line.separator") + + System.getProperty("line.separator") ; + addStatement(srcUnitRewrite, srcUnit, srcDec[0],importPushRef,TypeDeclaration.MODIFIERS2_PROPERTY); + + // Handling �N���X�� updateAvailable() ���\�b�h�� updateRequest() ���\�b�h�̍Ō�ɁCShipping �N���X�� + // updateHandling() ���\�b�h���t�B�[���h value �������Ƃ��ēn���ČĂяo���s��lj�����D + Type srcType = searchFieldDeclaration(srcUnit, "State").getType(); + for (var update : messages) { + var invocations = getPutMethodInvocations(update); + String code = ""; + if (invocations.size() == 0) + code += "Form "; + code += "form = new Form();" + System.getProperty("line.separator"); + if (srcType instanceof ParameterizedType) { + var ptype = (ParameterizedType) srcType; + if (ptype.getType().toString().equals("List")) { + var typeArg = (Type) ptype.typeArguments().get(0); + code += "for (" + typeArg + " i: this.value) {" + System.getProperty("line.separator"); + code += "\t form.param(\"" + srcValue + "\", new ObjectMapper().writeValueAsString(i));" + + System.getProperty("line.separator"); + code += "}" + System.getProperty("line.separator"); + } + if (ptype.getType().toString().equals("Map.Entry")) { + code += "form.param(\"" + srcValue + "\", new ObjectMapper().writeValueAsString(this.value));" + + System.getProperty("line.separator"); + } + } else { + code += "form.param(\"" + srcValue + "\", new ObjectMapper().writeValueAsString(this.value));" + + System.getProperty("line.separator"); + } + + if (invocations.size() == 0) + code += "Entity "; + code += "entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED);" + + System.getProperty("line.separator"); + if (invocations.size() == 0) + code += "String "; + code += "result = client.target(\"http://localhost:8080\").path(" + dstValue + + ").request().put(entity, String.class);" + System.getProperty("line.separator"); + addStatementLast(srcUnitRewrite, srcUnit, update.getBody(), code, Block.STATEMENTS_PROPERTY); + } + + var dstDec = new TypeDeclaration[1]; + descriptor.getDistinationClass().accept(new ASTVisitor() { + @Override + public boolean visit(TypeDeclaration node) { + dstDec[0] = node; + return false; + } + }); + ASTRewrite dstUnitRewrite = ASTRewrite.create(dstDec[0].getAST()); + + // Shipping �N���X�̃t�B�[���h handling ���폜����D + deleteASTNode(dstUnitRewrite, dstUnit, searchFieldDeclaration(dstUnit, "PullReference", srcValue)); + + // Shipping �N���X�ɏo�Ɏw���̓��e��ۑ����邽�߂̃t�B�[���h Item value ��lj�����D + Type dstType = searchMethodDeclaration(dstUnit, "Getter").getReturnType2(); + + String stateCode = "@State" + System.getProperty("line.separator") + dstType.toString() + " value;"; + addStatement(dstUnitRewrite, dstUnit, dstDec[0], stateCode); + // Shipping �N���X�� void updateHandling(ItemHandling handling) ���\�b�h��lj�����D + // Shipping �N���X�� getValue() + // ���\�b�h���ōs���Ă����C���[�U�̓��͂ɑ΂��鏈�����e(ItemHandling)�����Ƃɏo�Ɏw���̓��e(Item)���쐬���鏈�����CupdateHandling() + // ���\�b�h�Ɉړ����C�o�Ɏw���̓��e�� value �t�B�[���h�ɕۑ�����悤�ɂ���D + String updateCode = generatePutMethod(dstType, new Type[] { srcType }, new String[] { srcValue }); + addStatement(dstUnitRewrite, dstUnit, dstDec[0], updateCode); + // Shipping �N���X�� getValue() ���\�b�h�� value �t�B�[���h�̒l��Ԃ��悤�ɏ���������D + Statement statement = (Statement) dstUnitRewrite.createStringPlaceholder("{ return this.value; }", + ASTNode.VARIABLE_DECLARATION_STATEMENT); + replaceASTNode(dstUnitRewrite, dstUnit, searchMethodDeclaration(dstUnit, "Getter").getBody(), statement); + + try { + applyRewrite(srcUnit, srcUnitRewrite, pm); + applyRewrite(dstUnit, dstUnitRewrite, pm); + + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + + public String generatePutMethod(Type updatedValueType, Type[] paramTypes, String[] srcNames) { + String paramType = "String"; + + if (paramTypes[0] instanceof ParameterizedType) { + //�]�����̌^�����X�g�������ꍇ, PUT���\�b�h���󂯂Ƃ�p�����[�^�[�̌^��List�ɂ��� + var ptype = (ParameterizedType) paramTypes[0]; + if (ptype.getType().toString().equals("List")) { + paramType = "List"; + } + } + + var args = "@FormParam(\"" + srcNames[0] + "\") "+paramType+" " + srcNames[0] + "_json"; + String srcs = Arrays.stream(srcNames).map(x -> "\"" + x + "\"").collect(Collectors.joining(", ")); + String result = "@PUT" + System.getProperty("line.separator") + "@Message({" + srcs + "})" + + System.getProperty("line.separator") + "public void update" + "(" + args + + ") throws JsonProcessingException {" + System.getProperty("line.separator"); + + // �^�錾 + for (int i = 0; i < paramTypes.length; i++) { + String initializer = ""; + if (paramTypes[i] instanceof ParameterizedType) { + var ptype = (ParameterizedType) paramTypes[i]; + if (ptype.getType().toString().equals("List")) { + initializer = " = new ArrayList<>()"; + } + } + result += paramTypes[i].toString() + " " + srcNames[i] + initializer + ";" + System.getProperty("line.separator"); + } + for (int i = 0; i < paramTypes.length; i++) { + result += "{" + System.getProperty("line.separator") + "\t"; + if (paramTypes[i] instanceof ParameterizedType) { + var ptype = (ParameterizedType) paramTypes[i]; + if (ptype.getType().toString().equals("List")) { + var argType = (Type)ptype.typeArguments().get(0); + String initializer = ""; + if(argType instanceof ParameterizedType) { + if (((ParameterizedType)argType).getType().toString().equals("Map.Entry")) { + initializer = " new ObjectMapper().readValue(str, HashMap.class);"; + } + //((ParameterizedType)argType).getType(); + }else { + if(argType.toString().equals("Integer")) { + initializer = " Integer.parseInt(str);"; + } + } + result += "for(String str: "+srcNames[i]+"_json ){ " + System.getProperty("line.separator"); + result += convertType(argType) +" i =" + initializer + System.getProperty("line.separator"); + result += srcNames[i].toString()+".add("; + // String value, String tmpValue, Type type + result += geterateParameterizedTypeStatements("i", "i", argType); + result += ");" + System.getProperty("line.separator"); + result += "}" + System.getProperty("line.separator"); + } + if (ptype.getType().toString().equals("Map.Entry")) { + result += convertType(ptype) + " i = new ObjectMapper().readValue(" + srcNames[i] + + "_json, HashMap.class);" + System.getProperty("line.separator") + "\t"; + var mapValue = "i"; + var typeArg = ptype.typeArguments().get(1); + if(typeArg instanceof ParameterizedType) { + if(( (ParameterizedType) ptype.typeArguments().get(1)).getType().toString().equals("Map.Entry")){ + mapValue += ".entrySet().iterator().next().getValue()"; + } + } + + result += srcNames[i] + " = new AbstractMap.SimpleEntry<>(i.entrySet().iterator().next().getKey(), " + + geterateParameterizedTypeStatements("i", mapValue, (Type) ptype.typeArguments().get(1)) + ");" + + System.getProperty("line.separator"); + } + } + + result += "}" + System.getProperty("line.separator"); + + } + + { + var returnStatement = new ReturnStatement[1]; + searchMethodDeclaration(descriptor.getDistinationClass(), "Getter").accept(new ASTVisitor() { + @Override + public boolean visit(ReturnStatement node) { + returnStatement[0] = node; + return super.visit(node); + } + }); + ; + result += "this.value = " + returnStatement[0].getExpression() + ";" + System.getProperty("line.separator"); + } + result += "}" + System.getProperty("line.separator"); + + return result; + } + + /** + * + * @param astRewrite + * @param cu + * @param astNode + * @param replasement + */ + private void replaceASTNode(ASTRewrite astRewrite, CompilationUnit cu, ASTNode astNode, ASTNode replasement) { + TextEditGroup dstEditGroup = new TextEditGroup("new class edit group"); + astRewrite.replace(astNode, replasement, dstEditGroup); + } + + private void addStatement(ASTRewrite astRewrite, CompilationUnit cu, ASTNode astNode, String statementCode) { + ListRewrite dstUnitRewriteList = astRewrite.getListRewrite(astNode, TypeDeclaration.BODY_DECLARATIONS_PROPERTY); + PackageDeclaration dstPackageDeclaration = cu.getPackage(); + + Statement statement = (Statement) astRewrite.createStringPlaceholder(statementCode, + ASTNode.VARIABLE_DECLARATION_STATEMENT); + + astRewrite.set(cu, CompilationUnit.PACKAGE_PROPERTY, dstPackageDeclaration, null); + TextEditGroup dstEditGroup = new TextEditGroup("new class edit group"); + dstUnitRewriteList.insertFirst(statement, dstEditGroup); + } + + private void addStatement(ASTRewrite astRewrite, CompilationUnit cu, ASTNode astNode, String statementCode, + ChildListPropertyDescriptor childListPropertyDescriptor) { + ListRewrite dstUnitRewriteList = astRewrite.getListRewrite(astNode, childListPropertyDescriptor); + PackageDeclaration dstPackageDeclaration = cu.getPackage(); + + Statement statement = (Statement) astRewrite.createStringPlaceholder(statementCode, + ASTNode.VARIABLE_DECLARATION_STATEMENT); + + astRewrite.set(cu, CompilationUnit.PACKAGE_PROPERTY, dstPackageDeclaration, null); + TextEditGroup dstEditGroup = new TextEditGroup("new class edit group"); + dstUnitRewriteList.insertFirst(statement, dstEditGroup); + } + + private void addStatementBefore(ASTRewrite astRewrite, CompilationUnit cu, ASTNode astNode, ASTNode nextNode, + String statementCode, ChildListPropertyDescriptor childListPropertyDescriptor) { + ListRewrite dstUnitRewriteList = astRewrite.getListRewrite(astNode, childListPropertyDescriptor); + PackageDeclaration dstPackageDeclaration = cu.getPackage(); + + Statement statement = (Statement) astRewrite.createStringPlaceholder(statementCode, + ASTNode.VARIABLE_DECLARATION_STATEMENT); + + astRewrite.set(cu, CompilationUnit.PACKAGE_PROPERTY, dstPackageDeclaration, null); + TextEditGroup dstEditGroup = new TextEditGroup("new class edit group"); + dstUnitRewriteList.insertBefore(statement, nextNode, dstEditGroup); + } + + private void addStatementLast(ASTRewrite astRewrite, CompilationUnit cu, ASTNode astNode, String statementCode, + ChildListPropertyDescriptor childListPropertyDescriptor) { + ListRewrite dstUnitRewriteList = astRewrite.getListRewrite(astNode, childListPropertyDescriptor); + PackageDeclaration dstPackageDeclaration = cu.getPackage(); + + Statement statement = (Statement) astRewrite.createStringPlaceholder(statementCode, + ASTNode.VARIABLE_DECLARATION_STATEMENT); + + astRewrite.set(cu, CompilationUnit.PACKAGE_PROPERTY, dstPackageDeclaration, null); + TextEditGroup dstEditGroup = new TextEditGroup("new class edit group"); + dstUnitRewriteList.insertLast(statement, dstEditGroup); + } + + private void deleteASTNode(ASTRewrite astRewrite, CompilationUnit cu, ASTNode astNode) { + TextEditGroup dstEditGroup = new TextEditGroup("new class edit group"); + astRewrite.remove(astNode, dstEditGroup); + } + + /** + * ������̐�[�Ɩ����ɂ���_�u���N�H�[�e�[�V�������폜���郁�\�b�h + * + * @param str + * @return + */ + + private String annotationValueCase(String str) { + return Character.toLowerCase(str.charAt(0)) + (str.length() > 1 ? str.substring(1) : ""); + } + + private void changeGetter(IProgressMonitor pm) { + + CompilationUnit unit = descriptor.getDistinationClass(); + var getter = searchMethodDeclaration(unit, "Getter"); + ASTNode[] changed = new ASTNode[1]; + + getter.accept(new ASTVisitor() { + @Override + public boolean visit(MethodInvocation node) { + + changed[0] = node; + return false; + } + }); + ASTRewrite rewrite = ASTRewrite.create(changed[0].getAST()); + ListRewrite[] rewrites = new ListRewrite[1]; + FieldDeclaration fd = searchFieldDeclaration(unit, "State"); + Statement pushable = (Statement) rewrite.createStringPlaceholder(fd.fragments().get(0).toString(), + ASTNode.EMPTY_STATEMENT); + PackageDeclaration packageDeclaration = unit.getPackage(); + rewrite.set(unit, CompilationUnit.PACKAGE_PROPERTY, packageDeclaration, null); + TextEditGroup editGroup = new TextEditGroup("new class edit group"); + rewrites[0] = rewrite.getListRewrite(changed[0], MethodInvocation.TYPE_ARGUMENTS_PROPERTY); + rewrites[0].insertFirst(pushable, editGroup); + IPath path = unit.getJavaElement().getPath(); + // �V�K�t�@�C���쐬 + try { + ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager(); + bufferManager.connect(path, LocationKind.IFILE, pm); + ITextFileBuffer textFileBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE); + IDocument document = textFileBuffer.getDocument(); + TextEdit edit = rewrite.rewriteAST(document, null); + edit.apply(document); + textFileBuffer.commit(pm /* ProgressMonitor */, true/* Overwrite */); + IDocumentProvider provider; + } catch (Exception e) { + e.printStackTrace(); + } + } + + private MethodDeclaration createGetCtargetMethod(AST ast) { + + MethodDeclaration newDeclaration = ast.newMethodDeclaration(); + Block body = ast.newBlock(); + + // ���\�b�h����ݒ� + newDeclaration.setName(ast.newSimpleName("test")); + + // �߂�l�̌^��Ctarget�ɐݒ� + newDeclaration.setReturnType2(ast.newSimpleType(ast.newName("int"))); + + // �߂�l�̒l��ݒ� + ReturnStatement returnStatement = ast.newReturnStatement(); + FieldAccess access = ast.newFieldAccess(); + access.setName(ast.newSimpleName("result")); + access.setExpression(ast.newThisExpression()); + + returnStatement.setExpression(access); + + body.statements().add(returnStatement); + newDeclaration.setBody(body); + newDeclaration.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); + return newDeclaration; + } + + /** + * �N���X�t�@�C����Ώۂ�,�A�m�e�[�V�������ƒl����,���ꂪ�t�^����Ă���t�B�[���h��Ԃ����\�b�h. �A�m�e�[�V�����̒l�����������Ɋ܂߂鏈���͖����� + * + * @param cu �Ώۂ̃N���X�t�@�C�� + * @param annotationName �A�m�e�[�V������ + * @param value �A�m�e�[�V�����̒l + * @return �A�m�e�[�V�������t�^���ꂽ�t�B�[���h�̐錾�� + */ + private FieldDeclaration searchFieldDeclaration(CompilationUnit cu, String annotationName, String... values) { + FieldDeclaration[] result = new FieldDeclaration[1]; + cu.accept(new ASTVisitor() { + @Override + public boolean visit(FieldDeclaration node) { + if (hasMatchAnnotation(node, node.modifiers(), annotationName, values)) { + result[0] = node; + } + return super.visit(node); + } + }); return result[0]; } + /** - * AST�𕶎���̃R�[�h�ɖ߂����\�b�h - * - * @param code - * ���̃R�[�h - * @param unit - * ASTVisitor�ő�����s�������c - * @return �\�[�X�R�[�h - */ - private static String getCode(String code, CompilationUnit unit) { - IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); - IFile file = workspaceRoot.getFile(unit.getTypeRoot().getPath()); - IPath path = file.getFullPath(); + * �N���X�t�@�C����Ώۂ�,�A�m�e�[�V�������ƒl����,���ꂪ�t�^����Ă���t�B�[���h��Ԃ����\�b�h. �A�m�e�[�V�����̒l�����������Ɋ܂߂鏈���͖����� + * + * @param cu �Ώۂ̃N���X�t�@�C�� + * @param annotationName �A�m�e�[�V������ + * @param value �A�m�e�[�V�����̒l + * @return �A�m�e�[�V�������t�^���ꂽ�t�B�[���h�̐錾�� + */ + private MethodDeclaration searchMethodDeclaration(CompilationUnit cu, String annotationName, String... values) { + MethodDeclaration[] result = new MethodDeclaration[1]; + cu.accept(new ASTVisitor() { + @Override + public boolean visit(MethodDeclaration node) { + if (hasMatchAnnotation(node, node.modifiers(), annotationName, values)) { + result[0] = node; + } + return super.visit(node); + } + }); + return result[0]; + } + + private boolean hasMatchAnnotation(ASTNode node, List modifiers, String annotationName, String... values) { + + for (var annotation : modifiers) { + // annotation���A�m�e�[�V��������Ȃ���,���̃��[�v�� + if (!(annotation instanceof Annotation)) + continue; + String annoName = ((Annotation) annotation).getTypeName().toString(); + // node�ɕt�^���ꂽ�A�m�e�[�V��������annotationName����v����ꍇ + if (annotationName.equals(annoName)) { + // annotation���l�̖����A�m�e�[�V�����������ꍇ + if (annotation instanceof MarkerAnnotation) { + return true; + } + + // annotation���l��1�‚̃A�m�e�[�V�����������ꍇ + if (annotation instanceof SingleMemberAnnotation) { + //�����Œl�̎w�肪���ɂ���Ă��Ȃ��Ƃ��̓A�m�e�[�V����������v�����i�K��true��Ԃ� + if (values.length == 0) + return true; + + SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation; + Expression tmp = singleMemberAnnotation.getValue(); + + IType itype = (IType) tmp.resolveTypeBinding().getJavaElement(); + String typename = itype.getTypeQualifiedName(); + if (tmp instanceof ArrayInitializer) { + + String value = singleMemberAnnotation.getValue().toString().substring(1, + singleMemberAnnotation.getValue().toString().length() - 1); + String[] arr = value.split(","); + for(int i=0; i) listA) { + + } + return false; + } + + /** + * AST�𕶎���̃R�[�h�ɖ߂����\�b�h + * + * @param code ���̃R�[�h + * @param unit ASTVisitor�ő�����s�������c + * @return �\�[�X�R�[�h + */ + private static String getCode(String code, CompilationUnit unit) { + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IFile file = workspaceRoot.getFile(unit.getTypeRoot().getPath()); + IPath path = file.getFullPath(); ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); ITextFileBuffer buffer = manager.getTextFileBuffer(path, LocationKind.IFILE); - IDocument eDoc = buffer.getDocument(); - - TextEdit edit = unit.rewrite(eDoc, null); - try { - edit.apply(eDoc); - return eDoc.get(); - } catch (Exception ex) { - ex.printStackTrace(); - return null; - } - } - private SearchPattern createSearchPattern() { - - String pattern = "A"; - int searchFor = IJavaSearchConstants.TYPE; - - int limitTo = IJavaSearchConstants.DECLARATIONS; - int matchRule = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH; - return SearchPattern.createPattern(pattern, searchFor, limitTo, matchRule); + IDocument eDoc = buffer.getDocument(); + + TextEdit edit = unit.rewrite(eDoc, null); + try { + edit.apply(eDoc); + return eDoc.get(); + } catch (Exception ex) { + ex.printStackTrace(); + return null; + } } + @Override public RefactoringParticipant[] loadParticipants(RefactoringStatus status, SharableParticipants sharedParticipants) throws CoreException { // TODO Auto-generated method stub return null; } - - private IJavaElement searchElement(IJavaElement parent,IAnnotation annotation, String value) { - IJavaElement[] result = new IJavaElement[1]; - String annotationName = annotation.getElementName(); - SearchPattern pattern = createSearchPattern(); - SearchParticipant[] participants = { SearchEngine.getDefaultSearchParticipant() }; - IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); - - SearchRequestor requestor = new SearchRequestor() { - @Override - public void acceptSearchMatch(SearchMatch match) throws CoreException { - IJavaElement element = (IJavaElement) match.getElement(); - - System.out.println(element.getElementType()); - ICompilationUnit icu = ((SourceType) element).getCompilationUnit(); - System.out.println("name:" + icu.getElementName()); - if (element.getElementName().equals(annotation.getElementName())) { - result[0] = element; - } - - System.out.printf("%s %d,%d\n", element.getElementName(), match.getOffset(), match.getLength()); - } - }; - try { - new SearchEngine().search(pattern, participants, scope, requestor, new NullProgressMonitor()); - } catch (CoreException e) { - e.printStackTrace(); - } - return result[0]; - } } diff --git a/src/org/ntlab/pushPullRefactoring/PushPullRefactoringHandler.java b/src/org/ntlab/pushPullRefactoring/PushPullRefactoringHandler.java index 8bf19c6..14957d4 100644 --- a/src/org/ntlab/pushPullRefactoring/PushPullRefactoringHandler.java +++ b/src/org/ntlab/pushPullRefactoring/PushPullRefactoringHandler.java @@ -1,7 +1,6 @@ package org.ntlab.pushPullRefactoring; import java.lang.reflect.InvocationTargetException; - import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler; @@ -13,6 +12,7 @@ import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMemberValuePair; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; @@ -21,9 +21,14 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.MarkerAnnotation; +import org.eclipse.jdt.core.dom.NormalAnnotation; import org.eclipse.jdt.core.dom.SimpleType; +import org.eclipse.jdt.core.dom.SingleMemberAnnotation; +import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; @@ -47,7 +52,10 @@ import org.eclipse.ui.handlers.HandlerUtil; public class PushPullRefactoringHandler implements IHandler { - + boolean isPossible = false; + CompilationUnit srcUnit = null; + CompilationUnit dstUnit = null; + boolean isPushToPull ; @Override public void addHandlerListener(IHandlerListener handlerListener) { // TODO Auto-generated method stub @@ -59,53 +67,81 @@ // TODO Auto-generated method stub } - + private IJavaProject javaProject; /** * ���j���[�ŁuPushPullRefactoring...�v���������ꂽ�Ƃ��Ɏ��s */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { - CompilationUnit srcUnit = null; - CompilationUnit dstUnit = null; + Measurement.start(); try { + //�I��Ώۂ�AST���擾��,�������A�m�e�[�V�������t�^����Ă��邩���`�F�b�N. SourceField targetField = getTargetField(event); - - - SimpleType[] dstNode = new SimpleType[1]; CompilationUnit srcNode = (CompilationUnit) getASTNode(targetField.getCompilationUnit()); - srcNode.accept(new ASTVisitor() { - public boolean visit(FieldDeclaration node) { - for (Object v : node.fragments()) { - VariableDeclarationFragment var = (VariableDeclarationFragment) v; - if (var.getName().getIdentifier().equals(targetField.getElementName())) { - dstNode[0] = ((SimpleType) node.getType()); - - } + ASTNode targetNode = targetField.findNode(srcNode); + javaProject = targetField.getJavaProject(); + String annotationValue =""; + if(!(targetNode instanceof FieldDeclaration))return null; + for(var modifier : ((FieldDeclaration) targetNode).modifiers()) { + if(modifier instanceof SingleMemberAnnotation) { + var annotation =(SingleMemberAnnotation) modifier; + String name = annotation.getTypeName().toString(); + String value = annotation.getValue().toString(); + + if(name.equals("PushReference")) { + annotationValue = value; + isPushToPull = true; + }else if(name.equals("PullReference")) { + annotationValue = value; + isPushToPull = false; } - return true; + + if(name.equals("Pullable")&&value.equals("\"direct\"")) { + isPossible = true; + } + } - }); - + if(modifier instanceof MarkerAnnotation) { + var annotation =(MarkerAnnotation) modifier; + String name = annotation.getTypeName().toString(); + if(name.equals("Pushable")) { + isPossible = true; + } + } + } -// if (targetType == null) { -// return null; -// } -// IType sourceResource; -// String sourceResourceName; - - srcUnit = getSourceCompilationUnit(event); - dstUnit = getDistinationCompilationUnit(event, dstNode[0].toString()); - + if(!isPossible)return null; + + + try { + if(isPushToPull) { + + srcUnit = getCompilationUnitByEvent(event); + dstUnit = getAnotherCompilationUnit(event, annotationValue); + //dstUnit = getAnotherCompilationUnit(event, annotationValue, javaProject); + }else { + + srcUnit = getAnotherCompilationUnit(event, annotationValue); + dstUnit = getCompilationUnitByEvent(event); + } + } catch (JavaModelException e) { + e.printStackTrace(); + } + + + } catch (JavaModelException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } + PushPullRefactoringContribution contribution = (PushPullRefactoringContribution)RefactoringCore.getRefactoringContribution(PushPullRefactoring.ID); PushPullDescriptor descriptor = (PushPullDescriptor) contribution.createDescriptor(); descriptor.setSourceClass(srcUnit); descriptor.setDistinationClass(dstUnit); + descriptor.setPushToPull(isPushToPull); try { PushPullRefactoring refactoring = (PushPullRefactoring) contribution.createRefactoring(descriptor, null); @@ -122,22 +158,6 @@ } return null; } - // -// private SourceField getTargetField(ExecutionEvent event) { -// SourceField targetType = null; -// -// try { -// targetType = codeResolve(event); -// } catch (JavaModelException e) { -// return null; -// } -// -// if (!(targetType instanceof IType)) { -// return null; -// } -// -// return targetType; -// } private SourceField getTargetField(ExecutionEvent event) throws JavaModelException { IEditorInput editorInput = HandlerUtil.getActiveEditorInput(event); @@ -192,6 +212,27 @@ result.recordModifications(); return result; } + private CompilationUnit getCompilationUnitByEvent(ExecutionEvent event) throws JavaModelException { + + IEditorInput editorInput = HandlerUtil.getActiveEditorInput(event); + ITypeRoot typeRoot = JavaUI.getEditorInputTypeRoot(editorInput); + ICompilationUnit sourceClass = (ICompilationUnit)typeRoot; + + ASTParser parser = ASTParser.newParser(AST.JLS8); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setResolveBindings(true); + parser.setSource(sourceClass); + CompilationUnit result = (CompilationUnit) parser.createAST(null); + result.recordModifications(); + return result; + } + private SearchPattern createSearchPattern() { + String pattern = "Resource"; // �A�m�e�[�V������ + int searchFor = IJavaSearchConstants.ANNOTATION_TYPE; + int limitTo = IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE; // �A�m�e�[�V�������g���Ă���ӏ������� + int matchRule = SearchPattern.R_CASE_SENSITIVE; + return SearchPattern.createPattern(pattern, searchFor, limitTo, matchRule); + } private CompilationUnit getDistinationCompilationUnit(ExecutionEvent event, String typeName) throws JavaModelException { IEditorInput editorInput = HandlerUtil.getActiveEditorInput(event); @@ -201,6 +242,7 @@ int matchRule = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH; SearchPattern searchPattern = SearchPattern.createPattern(pattern, searchFor, limitTo, matchRule); +// searchPattern = createSearchPattern(); SearchParticipant[] participants = { SearchEngine.getDefaultSearchParticipant() }; IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); @@ -225,29 +267,6 @@ e.printStackTrace(); } - -// if (typeRoot instanceof ICodeAssist) { -// if (typeRoot instanceof ICompilationUnit) { -// -// ((ICompilationUnit) typeRoot).reconcile( -// ICompilationUnit.NO_AST, -// false /* don't force problem detection */, -// null /* use primary owner */, -// null /* no progress monitor */); -// } -// ITextSelection selection = (ITextSelection) HandlerUtil.getActiveMenuSelection(event); -//// ITextSelection selection = (ITextSelection) HandlerUtil.getCurrentSelection(event); -// IJavaElement[] elements = ((ICodeAssist)typeRoot).codeSelect(selection.getOffset() + selection.getLength(), 0); -// if (elements[0] instanceof SourceField) { -// IAnnotation annotation = ((SourceField) elements[0]).getAnnotation("PushReference"); -// IMemberValuePair[] values = annotation.getMemberValuePairs(); -// boolean f = annotation.exists(); -// //�����̒l�� -// ((SourceField) elements[0]).getElementName(); -// -// } -// -// } ASTParser parser = ASTParser.newParser(AST.JLS4); parser.setKind(ASTParser.K_COMPILATION_UNIT); parser.setResolveBindings(true); @@ -258,6 +277,121 @@ return (CompilationUnit)result; } + private CompilationUnit getAnotherCompilationUnit(ExecutionEvent event, String resourceName) throws JavaModelException { + + SearchPattern searchPattern = createSearchPattern(); + SearchParticipant[] participants = { SearchEngine.getDefaultSearchParticipant() }; + + //IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); + IJavaSearchScope scope = SearchEngine + .createJavaSearchScope(new IJavaElement[] { javaProject }, false); + + ICompilationUnit[] icus = new ICompilationUnit[1]; + SearchRequestor requestor = new SearchRequestor() { + @Override + public void acceptSearchMatch(SearchMatch match) throws CoreException { + IJavaElement element = (IJavaElement) match.getElement(); + + System.out.println(element.getElementType()); + + ASTParser parser = ASTParser.newParser(AST.JLS4); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setResolveBindings(true); + parser.setBindingsRecovery(true); + parser.setSource(((SourceType) element).getCompilationUnit()); + ASTNode result = parser.createAST(new NullProgressMonitor()); + ((CompilationUnit) result).recordModifications(); + result.accept(new ASTVisitor() { + @Override + public boolean visit(TypeDeclaration node) { + var modifiers = node.modifiers(); + for(var annotation : modifiers) { + if(annotation instanceof SingleMemberAnnotation) { + var singleMemberAnnotation = ( SingleMemberAnnotation)annotation; + var annotationName = singleMemberAnnotation.getValue().toString(); + if( singleMemberAnnotation.getTypeName().toString().equals("Resource") + && annotationName.equals(resourceName)) { + dstUnit = (CompilationUnit)result; + icus[0] = ((SourceType) element).getCompilationUnit(); + } + String annoName = ((Annotation)annotation).getTypeName().toString(); + } + + + } + return true; + } + }); + + + // icus[0] = ((SourceType) element).getCompilationUnit(); + //elementDst[0] = element; + + System.out.printf("%s %d,%d\n", element.getElementName(), match.getOffset(), match.getLength()); + } + }; + + try { + new SearchEngine().search(searchPattern, participants, scope, requestor, new NullProgressMonitor()); + } catch (CoreException e) { + e.printStackTrace(); + } + + ASTParser parser = ASTParser.newParser(AST.JLS8); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setResolveBindings(true); + parser.setBindingsRecovery(true); + parser.setSource(icus[0]); + ASTNode result = parser.createAST(new NullProgressMonitor()); + ((CompilationUnit) result).recordModifications(); + + return (CompilationUnit)result; + } + +private CompilationUnit getAnotherCompilationUnit(ExecutionEvent event, String resourceName ,IJavaProject javaProject) throws JavaModelException { + SearchPattern pattern = SearchPattern.createPattern(resourceName, + IJavaSearchConstants.CLASS, // �N���X�����B + IJavaSearchConstants.DECLARATIONS, // �錾��T���B + SearchPattern.R_EXACT_MATCH); // ���m�Ƀ}�b�`�B + SearchParticipant[] participants = { SearchEngine.getDefaultSearchParticipant() }; + + //IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); + IJavaSearchScope scope = SearchEngine + .createJavaSearchScope(new IJavaElement[] { javaProject }); + + ICompilationUnit[] icus = new ICompilationUnit[1]; + // �N���X���������P�B + // new SearchEngine().search���g���ꍇ�̓t�b�N����N���X��SearchRequestor�B + SearchRequestor requestor = new SearchRequestor() { + public void acceptSearchMatch(SearchMatch match) + throws CoreException { + Object javaElement = match.getElement(); + System.out.println(javaElement); + if (javaElement instanceof IType) { + IType type = (IType) javaElement; + String typeName = type.getFullyQualifiedName(); + icus[0] = ((SourceType) javaElement).getCompilationUnit(); + } + } + }; + + try { + new SearchEngine().search(pattern, participants, scope, requestor, new NullProgressMonitor()); + } catch (CoreException e) { + e.printStackTrace(); + } + + ASTParser parser = ASTParser.newParser(AST.JLS4); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setResolveBindings(true); + parser.setBindingsRecovery(true); + parser.setSource(icus[0]); + ASTNode result = parser.createAST(new NullProgressMonitor()); + ((CompilationUnit) result).recordModifications(); + + return (CompilationUnit)result; + } + private IAnnotation[] getValidAnnotations(ExecutionEvent event) { IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); diff --git a/src/org/ntlab/pushPullRefactoring/TargetFieldChecker.java b/src/org/ntlab/pushPullRefactoring/TargetFieldChecker.java new file mode 100644 index 0000000..a258fc1 --- /dev/null +++ b/src/org/ntlab/pushPullRefactoring/TargetFieldChecker.java @@ -0,0 +1,26 @@ +package org.ntlab.pushPullRefactoring; + +import org.eclipse.core.commands.ExecutionEvent; + +/** + * �I��Ώۂ̃t�B�[���h�������������`�F�b�N����N���X + * @author student + * + */ +public class TargetFieldChecker { + /** + * + */ + private boolean isPossible; + private RefactoringDirection direction; + + public static TargetFieldChecker checkTargetField(ExecutionEvent event) { + TargetFieldChecker result = new TargetFieldChecker(); + + return result; + } + public enum RefactoringDirection{ + PushToPull, + PullToPush + } +} diff --git a/src/org/ntlab/pushPullRefactoring/implement/IChangeSource.java b/src/org/ntlab/pushPullRefactoring/implement/IChangeSource.java new file mode 100644 index 0000000..4a033b2 --- /dev/null +++ b/src/org/ntlab/pushPullRefactoring/implement/IChangeSource.java @@ -0,0 +1,10 @@ +package org.ntlab.pushPullRefactoring.implement; + +import org.eclipse.jdt.core.dom.*; + +public interface IChangeSource { + void addField(CompilationUnit targetClass, FieldDeclaration fieldDec); + void addMethod(CompilationUnit targetClass, MethodDeclaration methodDec); + + +} diff --git a/src/org/ntlab/pushPullRefactoring/implement/jaxrs/RefactoringProcessorJaxRs.java b/src/org/ntlab/pushPullRefactoring/implement/jaxrs/RefactoringProcessorJaxRs.java new file mode 100644 index 0000000..d620e06 --- /dev/null +++ b/src/org/ntlab/pushPullRefactoring/implement/jaxrs/RefactoringProcessorJaxRs.java @@ -0,0 +1,22 @@ +package org.ntlab.pushPullRefactoring.implement.jaxrs; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.ntlab.pushPullRefactoring.implement.IChangeSource; + +public class RefactoringProcessorJaxRs implements IChangeSource{ + + @Override + public void addField(CompilationUnit targetClass, FieldDeclaration fieldDec) { + // TODO Auto-generated method stub + + } + + @Override + public void addMethod(CompilationUnit targetClass, MethodDeclaration methodDec) { + // TODO Auto-generated method stub + + } + +}