您的位置:首页 > 编程语言 > Java开发

修改 eclipse 默认的 toString 模板, 自动对敏感字段进行 *** 处理

2016-06-12 01:16 666 查看
简介:

  eclipse 默认可以生成 toString 方法, 但是自动生成的代码有时候满足不了实际要求, 这里演示一下通过修改 eclipse 源码的方式来改变自动生成的 toString 方法.

1. 目标

1.1 将默认的 toString 模板修改为

  {${member.name()}=${member.value}, ${otherMembers}}

1.2 Code style 默认选中 StringBuilder/StringBuffer

1.3 toString 方法中每个字段占一行

1.4 toString 方法中自动对敏感字段进行 *** 处理

# 修改后截图如下:





2. 依赖 jar

eclipse_home\plugins\com.ibm.icu_50.1.1.v201304230130.jar

eclipse_home\plugins\org.eclipse.core.commands_3.6.100.v20130515-1857.jar

eclipse_home\plugins\org.eclipse.core.resources_3.8.101.v20130717-0806.jar

eclipse_home\plugins\org.eclipse.core.runtime_3.9.100.v20131218-1515.jar

eclipse_home\plugins\org.eclipse.equinox.common_3.6.200.v20130402-1505.jar

eclipse_home\plugins\org.eclipse.jdt.core_3.9.2.v20140114-1555.jar

eclipse_home\plugins\org.eclipse.jdt.ui_3.9.2.v20131106-1600.jar

eclipse_home\plugins\org.eclipse.jface_3.9.1.v20130725-1141.jar

eclipse_home\plugins\org.eclipse.swt.win32.win32.x86_3.102.1.v20140206-1358.jar

eclipse_home\plugins\org.eclipse.ui.workbench_3.105.2.v20140211-1711.jar

3. download eclipse source code

  http://archive.eclipse.org/eclipse/downloads/
  
4. 需要修改的文件

4.1 修改 toString 的默认模板

   org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringTemplateParser

   org.eclipse.jdt.internal.ui.dialogs.GenerateToStringDialog

   # GenerateToStringDialog 文件内容不需要修改, 只需要重新编译一下


   

4.2 Code style 默认选中 StringBuilder/StringBuffer

   org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.ToStringGenerationSettings


   

4.3 toString 方法中自动对敏感字段进行 *** 处理

   org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration.StringBuilderGenerator



/*******************************************************************************
* Copyright (c) 2008, 2011 Mateusz Matela and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html *
* Contributors:
*     Mateusz Matela <mateusz.matela@gmail.com> - [code manipulation] [dcr] toString() builder wizard - https://bugs.eclipse.org/bugs/show_bug.cgi?id=26070 *******************************************************************************/
package org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.NamingConventions;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.InfixExpression.Operator;

/**
* <p>
* Implementation of <code>AbstractToStringGenerator</code> that creates <code>toString()</code>
* method using <code>StringBuilder</code> (or <code>StringBuffer</code> for old versions of JDK)
* </p>
* <p>
* Generated methods look like this:
*
* <pre>
* public String toString() {
* 	StringBuilder builder= new StringBuilder();
* 	builder.append("FooClass( field1=");
* 	builder.append(field1);
* 	builder.append(", field2=");
* 	builder.append(field2);
* 	builder.append(" )");
* 	return builder.toString();
* }
* </pre>
*
* </p>
*
* @since 3.5
*/
public class StringBuilderGenerator extends AbstractToStringGenerator {
protected StringBuffer fBuffer;

protected String fBuilderVariableName;

protected final String APPEND_METHOD_NAME= "append"; //$NON-NLS-1$

protected void flushBuffer(Block target) {
if (fBuffer.length() > 0) {
StringLiteral literal= fAst.newStringLiteral();
literal.setLiteralValue(fBuffer.toString());
if (target == null)
target= toStringMethod.getBody();
target.statements().add(fAst.newExpressionStatement(createMethodInvocation(fBuilderVariableName, APPEND_METHOD_NAME, literal)));
fBuffer.setLength(0);
}
}

@Override
protected void initialize() {
super.initialize();
fBuilderVariableName= createNameSuggestion(getContext().is50orHigher() ? "sb" : "sb", NamingConventions.VK_LOCAL); //$NON-NLS-1$ //$NON-NLS-2$
fBuffer= new StringBuffer();
VariableDeclarationFragment fragment= fAst.newVariableDeclarationFragment();
fragment.setName(fAst.newSimpleName(fBuilderVariableName));
ClassInstanceCreation classInstance= fAst.newClassInstanceCreation();
Name typeName= addImport(getContext().is50orHigher() ? "java.lang.StringBuilder" : "java.lang.StringBuffer"); //$NON-NLS-1$ //$NON-NLS-2$
classInstance.setType(fAst.newSimpleType(typeName));
fragment.setInitializer(classInstance);
VariableDeclarationStatement vStatement= fAst.newVariableDeclarationStatement(fragment);
vStatement.setType(fAst.newSimpleType((Name)ASTNode.copySubtree(fAst, typeName)));
toStringMethod.getBody().statements().add(vStatement);
}

@Override
protected void complete() throws CoreException {
flushBuffer(null);
super.complete();
ReturnStatement rStatement= fAst.newReturnStatement();
rStatement.setExpression(createMethodInvocation(fBuilderVariableName, "toString", null)); //$NON-NLS-1$
toStringMethod.getBody().statements().add(rStatement);
}

protected void addElement(Object element, Block block) {
if (element instanceof String)
fBuffer.append((String)element);
if (element instanceof Expression) {
flushBuffer(block);
block.statements().add(fAst.newExpressionStatement(createMethodInvocation(fBuilderVariableName, APPEND_METHOD_NAME, (Expression)element)));
}
}

@Override
protected void addMemberCheckNull(Object member, boolean addSeparator) {
IfStatement ifStatement= fAst.newIfStatement();
ifStatement.setExpression(createInfixExpression(createMemberAccessExpression(member, true, true), Operator.NOT_EQUALS, fAst.newNullLiteral()));
Block thenBlock= fAst.newBlock();
flushBuffer(null);
String[] arrayString= getContext().getTemplateParser().getBody();
for (int i= 0; i < arrayString.length; i++) {
addElement(processElement(arrayString[i], member), thenBlock);
}
if (addSeparator)
addElement(getContext().getTemplateParser().getSeparator(), thenBlock);
flushBuffer(thenBlock);

if (thenBlock.statements().size() == 1 && !getContext().isForceBlocks()) {
ifStatement.setThenStatement((Statement)ASTNode.copySubtree(fAst, (ASTNode)thenBlock.statements().get(0)));
} else {
ifStatement.setThenStatement(thenBlock);
}
toStringMethod.getBody().statements().add(ifStatement);
}

@Override
protected void addElement(Object element) {
addElement(element, toStringMethod.getBody());
}

//////////////////// 以下为新添加的内容  //////////////////////////////
/**
* 添加成员信息
*/
@SuppressWarnings("unchecked")
protected void addMember(Object member, boolean addSeparator) {
flushBuffer(null);

List<Object> objList = new ArrayList<Object>();
Object fieldName = null;
Object fieldValue = null;
String templateElement = null;
StringBuilder sb = new StringBuilder();

String[] stringArray = this.fContext.getTemplateParser().getBody();
for (int i = 0; i < stringArray.length; i++) {
templateElement = stringArray[i];
if (templateElement.equals("${member.name}") || templateElement.equals("${member.name()}")) {
fieldName = processElement(stringArray[i], member);
objList.add(fieldName);
continue;
} else if (templateElement == "${member.value}") {
fieldValue = processElement(stringArray[i], member);
if (isSensitiveField(fieldName)) {
fieldValue = "*******";
}
objList.add(fieldValue);
continue;
} else {
objList.add(processElement(stringArray[i], member));
}
}
if (addSeparator) {
objList.add(this.fContext.getTemplateParser().getSeparator());
}

Expression currExpression = null;
for (Object element : objList) {
if (element instanceof String) {
sb.append(element);
} else if (element instanceof Expression) {
if (sb.length() != 0) {
StringLiteral literal = this.fAst.newStringLiteral();
literal.setLiteralValue(sb.toString());
currExpression = getNextExpression(currExpression, literal);
sb.delete(0, sb.length());
}
currExpression = getNextExpression(currExpression, (Expression)element);
}
}
if (sb.length() != 0) {
StringLiteral literal = this.fAst.newStringLiteral();
literal.setLiteralValue(sb.toString());
currExpression = getNextExpression(currExpression, literal);
sb.delete(0, sb.length());
}
this.toStringMethod.getBody().statements().add(this.fAst.newExpressionStatement(currExpression));
}

/**
* 计算新的表达式
* @param currExpression
* @param argument
* @return
*/
@SuppressWarnings("unchecked")
private Expression getNextExpression(Expression currExpression, Expression argument) {
MethodInvocation invocation = this.fAst.newMethodInvocation();
if (currExpression == null) {
invocation.setExpression(this.fAst.newName(this.fBuilderVariableName));
} else {
invocation.setExpression(currExpression);
}
invocation.setName(this.fAst.newSimpleName("append"));
invocation.arguments().add(argument);
return invocation;
}

/**
* 判断是否是敏感字段
* @param fieldName
* @return
*/
private boolean isSensitiveField(Object fieldName) {
String name = String.valueOf(fieldName).toLowerCase(Locale.US);
String[] words = new String[]{"pass", "pwd", "session", "token"};
for (String word : words) {
if (name.contains(word)) {
return true;
}
}
return false;
}
//////////////////// end  //////////////////////////////
}
5. 用编译出来的 *.class 文件替换 jar 包中的内容

   org.eclipse.jdt.ui_3.9.2.v20131106-1600.jar

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: