Какая технология может преобразовать текст данным образом?

Имеется большое количество методов, которые надо переписать определённым образом. Для примера, вот исходный метод:

/**
 * Finds all
 * @param id    the id
 * @param codes list of codes
 * @return entities
*/
@GET
@Path("/get")
@Produces(APPLICATION_JSON)
public List<Entity> get(@QueryParam("id") Integer id, @QueryParam("barcodes") List<Long> codes) {
  return entityBean.findByIdAndCodes(id, codes);
}

Он должен быть переписан таким образом:

/**
 * Finds all
 * @param id    the id
 * @param codes list of codes
 * @return entities
*/
@RequestLine("GET " + PATH + "get")
List<Entity> get(@Param("id") Integer id, @Param("codes") List<Long> codes);

То есть переписывание кода должно идти по следующему сценарию:

  • Тело метода заменяется символом ;.
  • У метода уходит модификатор доступа.
  • Уходят аннотации @GET, @Path и @Produces.
  • Комментарий переносится без изменений.
  • Над методом формируется строка такого вида: @RequestLine("[аннотация @GET без символа @]" + PATH + "[содержимое аннотации @Path без первого символа /]").
  • Аннотации параметров метода меняются с @QueryParam на @Param.

Возвращаемый тип, количество параметров и название могут быть разными в разных методах. Также вместо аннотации @GET может быть @POST или @DELETE.

Какая технология позволит мне выполнить такое преобразование кода наиболее эффективно?


Ответы (1 шт):

Автор решения: Zhenyria

Для решения проблемы я использовал Live template - это инструмент в IDEA, который позволяет создавать удобные шаблоны для преобразования / формирования кода.

Сам шаблон выглядел вот так:

$METHOD$

Код шаблона (для преобразования текста я использовал скрипт, написанный на Groovy):

groovyScript("D:\\method.groovy", clipboard())

groovyScript() здесь служит для указания скрипта, который будет использоваться для преобразования текста (первый аргумент - сам скрипт или путь к файлу со скриптом, второй аргумент - текстовая переменная, передающаяся в скрипт). clipboard() - это содержимое буфера обмена.

Сам скрипт:

def result = '';

def commentMatcher = _1 =~ "(/\\*{2}[^/]*\\*/)";
if (commentMatcher.find()) result = commentMatcher[0][0];

result += '\r\n@RequestLine("';
def httpMethodMatcher = _1 =~ "@(GET|POST|DELETE)";
if (httpMethodMatcher.find()) {
    result += httpMethodMatcher[0][1];
    result += ' " + PATH + ';
}

def isSignatureMatcherFindAnything = false;
def signatureMatcher = _1 =~ "(public |)([0-9a-zA-Z<>._,]*) ([a-zA-Z]*)(\\([^{]*\\))\\s*(throws [a-zA-Z0-9]+|)";
if (signatureMatcher.find()) {
    isSignatureMatcherFindAnything = true;
    result += '"';
    result += signatureMatcher[0][3].replaceAll('([A-Z])', '-$1').toLowerCase().replaceAll('^_', '');
}

def paramsMatcher = signatureMatcher[0][4] =~ "(@QueryParam)(\\(\"([a-zA-Z0-9]+)\"\\))";
if (paramsMatcher.find()) {
    result += '?'
    for (def i = 0; i < paramsMatcher.size(); i++) {
        if (i > 0) {
            result += '&';
        }
        def param = paramsMatcher[i][3];
        result += param;
        result += '={';
        result += param;
        result += '}';
    }
}
result += '")'

def headersMatcher = _1 =~ "(\\@Consumes)(\\((\"|)([^\"\\)]+)(\"|)\\))";
if (headersMatcher.find()) {
    result += '\r\n@Headers(';
    def content = headersMatcher[0][4];
    if (content.contains('8')) {
        result += 'CONTENT_TYPE_APPLICATION_JSON_UTF_8';
    } else {
        result += 'CONTENT_TYPE_APPLICATION_JSON';
    }
    result += ')';
}

if (isSignatureMatcherFindAnything) {
    result += '\r\n'
    result += signatureMatcher[0][2];
    result += ' ';
    result += signatureMatcher[0][3];
    result += signatureMatcher[0][4].replaceAll("@QueryParam", "@Param");
    
    if (signatureMatcher[0].size() == 6) {
        result += ' ';
        result += signatureMatcher[0][5];
    }
    
    result += ';';
}

return result;

Полученный Live template работает следующим образом:

  1. Копируем метод.
  2. Запускаем Live template (при помощи заданного ранее шортката).

Таким образом этот код:

/**
 * Finds all
 * @param id    the id
 * @param codes list of codes
 * @return entities
*/
@GET
@Path("/get")
@Produces(APPLICATION_JSON)
public List<Entity> get(@QueryParam("id") Integer id, @QueryParam("barcodes") List<Long> codes) {
  return entityBean.findByIdAndCodes(id, codes);
}

превращается в следующее:

/**
 * Finds all
 * @param id    the id
 * @param codes list of codes
 * @return entities
*/
@RequestLine("GET " + PATH + "get")
List<Entity> get(@Param("id") Integer id, @Param("codes") List<Long> codes);
→ Ссылка