diff --git a/src/org/ntlab/pushPullRefactoring/Push2PullRewrite.java b/src/org/ntlab/pushPullRefactoring/Push2PullRewrite.java new file mode 100644 index 0000000..d9da474 --- /dev/null +++ b/src/org/ntlab/pushPullRefactoring/Push2PullRewrite.java @@ -0,0 +1,271 @@ +package org.ntlab.pushPullRefactoring; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.Assignment; +import org.eclipse.jdt.core.dom.Block; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.ReturnStatement; +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.rewrite.ASTRewrite; + +public class Push2PullRewrite extends SourceRewriter{ + + public Push2PullRewrite(PushPullDescriptor descriptor) { + super(descriptor); + } + // TODO Auto-generated constructor stub + @Override + public void rewrite(IProgressMonitor pm) { + // TODO Auto-generated method stub + 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(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(); + } + + } + protected 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); + } + + } + + } + 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; + } + +}