Эх, не люблю писать бойлерплейты, ведь есть IntelliJ IDEA и Apache Velocity

в 17:50, , рубрики: intellij idea, java, Velocity, Программирование

Добрый день!

Речь в этой статье пойдет о том, как частично сократить объем кода, который зачастую приходится набирать вручную или откуда-то копипастить (боже упаси), средствами IntelliJ IDEA, а конкретнее — шаблонами файлов и кода. Если вы не достаточно знакомы с расширенным использованием возможностей этой IDE, то добро пожаловать под кат.

Не секрет, что зачастую приходится писать бойлерплейты — от простого создания точки входа программы до надоедающих скобок в JSON-ах. Сообщество программистов постоянно оптимизирует этот процесс — выпускаются фреймворки, микролибы, шаблонизаторы… Также дело значительно облегчают фичи IDE, в которой вы работаете — сюда относятся, например, автоподстановка или вышеупомянутые шаблоны файлов и кода.

IntelliJ IDEA file and code templates

Допустим, что мы хотим создать в проекте какой-либо файл. Для этого мы открываем проект через нашу любимую IDE, нажимаем хот-кей Alt+1, после чего появляется панель с деревом проекта. Далее кликаем ПКМ по директории, в которой нужно создать новый файл. Открывается вот такое контекстное меню:

image

Здесь нас, естественно, интересует пункт «New».

image

Как видим, здесь есть различные варианты — файл с расширением .java (Java Class), файл с расширением .kt (Kotlin File/Class), пакет и так далее. Также здесь есть секция с более специфичными названиями — HTML File, JavaFXApplication, Singleton. Если вы нажмете на что-нибудь из этого, то создадите файл, в котором Вот это все и есть File and Code Templates, то есть шаблоны файлов и кода. А под всеми шаблонами есть кнопка «Edit File Templates...» Она-то нас и интересует. Нажимаем её и видим такое окно:

image

Для среднего программиста на Java набор доступных в IDEA шаблонов достаточно бедноват. Но ему предоставлена богатая возможность редактировать их с помощью шаблонизатора под названием Apache Velocity. Про него есть несколько статей на Хабре, для дополнительного чтения я оставлю ссылки внизу статьи.

Что же он может? Рассмотрим картинку выше. Слева есть список доступных шаблонов (он внушительный, но это фикция, он довольно беден на полезности), сверху — вкладки с категориями шаблонов, центр занимает текстовое поле, в котором написан HTML-код, а снизу большой объем текста, помеченный как Description. Допустим, что я не веб-разработчик и в HTML не разбираюсь, поэтому выберем другой шаблон — например, Class.

image

Сразу замечаем не похожий на Джаву код вперемешку с Джава-кодом. Это и есть конструкции Apache Velocity.

Apache Velocity: как делать

Не будем погружаться в глубины API и документации, а разберемся с основными моментами, которые помогут нам писать свои шаблоны.

Обычно конструкции шаблонизатора мешают с обычным текстом, поэтому процесс несколько специфичен.

Основное:

$variable_name — обращение к переменной. Имя должно начинаться с латинской буквы и содержать только латинские буквы, цифры, а также символы "-" и "_".

#set($variable_name = "value") — присвоение переменной значения для дальнейшего использования в тексте.

#if(condition) stub #else stub #end — условный оператор. Вместо стабов можно подставлять то, что должно появиться в тексте, если условие выполняется (или не выполняется).

#include("another_template.txt") — подставляет содержимое указанного файла. Файлы, доступные для использования, должны быть указаны во вкладке Includes.

#parse("another_template.txt") — делает то же самое, что и #includes, но если файл содержит VTL (Velocity Template Language — то же, что и Apache Velocity), то он также будет исполнен.

#evaluate(string) — подставляет параметр и исполняет содержащийся в нем VTL.

Теперь о типах данных. Переменные VTL могут иметь следующие типы:

  • Строка
  • Число
  • Массив
  • Мап

Также стоит отметить, что строка здесь соответствует String-у в Джаве, поэтому у нее можно вызывать методы contains(), matches() и так далее.

Также для написания шаблонов в Джаве есть несколько predefined-переменных. Самая важная — ${NAME}, содержащая имя файла; ${PACKAGE_NAME}, содержащая имя пакета; есть переменные для времени, например, ${DAY}, содержащая сегодняшний день; есть возможность объявлять свои переменные, значение которых вам предложат задать, когда вы будете создавать файл по написанному шаблону. Вот так: ${VARIABLE_NAME}. Полный список всех predefined-переменных есть в текстбоксе Description.

Примеры?

Для пояснения всего вышесказанного, напишем несколько собственных шаблонов. Нажимаем в нашем окошке зеленый плюсик над списком шаблонов.

Точка входа в приложение

Однажды я обнаружил, что у Идеи нет шаблонов классов, содержащих public static void main(). Совсем (ну, или я их не нашел). С этого и началось мое знакомство с шаблонами IntelliJ IDEA и с VTL — я решил написать себе свой шаблон, с комментариями и vararg-ами.

Получилось так:

public class ${NAME} {
    public static void main(String... args) {
        
    }
}

Здесь все просто. Из VTL-специфичных игрушек здесь только ${NAME}, predefined-переменная. Зато я могу, например, вставить комментарий, содержащий сегодняшний день и имя автора.

/**
 *  Today is ${DATE}
 *  ${USER} is #if(${MINUTE}%1==0) the best #else not the best #end
*/
public class ${NAME} {
    public static void main(String... args) {
        
    }
}

Введем имя шаблона и сохраним его. После этого нажмем ПКМ где-нибудь у себя в проекте (советую создать тестовый проект, но можно поиграться и на продакшене) -> New -> Ваш шаблон. Вводим имя файла и видим:

image

Великолепно!

Шаблон для JUnit4-тестов

Более практичный и красивый пример. По соглашению об оформлении кода, тест-классы должны иметь в названии слово Test. Позаботимся о своей памяти и напишем вот такой шаблон:

import junit.framework.TestCase;

public class ${NAME}#if(!$NAME.contains("Test"))Test #end extends TestCase {
    @Override 
    public void setUp() {
        
    }
}

Теперь, если мы забудем при создании тест-кейса дописать в названии слово «Test», шаблон сделает это за нас!

Обратите внимание: здесь мы вызывали у строки метод contains. Чтобы вызывать методы строк, необходимо обращаться к переменной, опуская фигурные скобки. То же самое касается обращения к полям массивов и мап — никаких фигурных скобок!

Теперь сохраним шаблон и попробуем создать себе тест. Снова кликаем ПКМ на какой-нибудь директории -> New -> Ваш шаблон теста. Введем имя (без слова «Test»), создается вот такой файл:

image

Но это еще не все. Давайте удалим его и создадим заново с тем же именем, но на этот раз добавим в конце имени слово «Test». Что мы получаем? Абсолютно точно, никаких двух подряд идущих «Test»-ов.

image

Скрытый текст

На самом деле я просто вставил две одинаковые картинки, но это неважно. Оно работает!

Немного про схемы

В самом верху окна «File And Code Templates» есть выпадающий список, в котором есть два пункта — «Default» и «Project». Что это значит?

Это значит, что вы можете создавать шаблоны для всех проектов («Default»), либо только для текущего («Project»). Это называется схемы (Schemes) и конкретно в File and Code Templates их доступно только две, хотя в общих настройках их больше и можно создавать свои. Ну, неважно.

Что почитать

Упомянутые мною хабра-статьи, посвященные VTL

Да, она всего одна, потому что в процессе написания вторая куда-то потерялась.

Также есть английское руководство от IntelliJ

Но оно не раскрывает всех возможностей шаблонизации кода, хотя дает более полную характеристику юзабилити шаблонов.

И Getting Started с офф. сайта Apache Velocity

Заключение

File and Code Templates — весьма мощное средство IntelliJ IDEA, которое по какой-то причине мало освещено. Есть вещи, на которые сразу натыкаешься, начиная изучать предметную область, но шаблоны явно не относятся сюда — и зря. Срочно поделитесь этой информацией со своими друзьями и коллегами и посадите их писать шаблоны на VTL! Уговорите своего босса или владельца любимого open-source посадить человека оформлять contribution-гайды, вставляя в них шаблоны. Это — удобно!

Автор: Егор Трутенко

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js