package com.github.setial.intellijjavadocs.transformation; import com.github.setial.intellijjavadocs.model.JavaDoc; import com.github.setial.intellijjavadocs.model.JavaDocElements; import com.github.setial.intellijjavadocs.model.JavaDocTag; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * The type Java doc builder. * * @author Sergey Timofiychuk */ public class JavaDocBuilder { private StringBuilder builder; /** * Instantiates a new Java doc builder. */ public JavaDocBuilder() { builder = new StringBuilder(); } /** * Open the java doc section. * * @return the Java doc builder */ public JavaDocBuilder openJavaDoc() { builder.append(JavaDocElements.STARTING.getPresentation()); builder.append(JavaDocElements.LINE_START.getPresentation()); return this; } /** * Close the java doc section. * * @return the Java doc builder */ public JavaDocBuilder closeJavaDoc() { // add new line with asterisk if it's not new line if (!closeRegularJavaDoc()) { closeOneLineJavaDoc(); } builder.append(JavaDocElements.ENDING.getPresentation()); return this; } /** * Add new line to javadoc section. * * @return the Java doc builder */ public JavaDocBuilder addNewLine() { builder.append(JavaDocElements.NEW_LINE.getPresentation()); builder.append(JavaDocElements.LINE_START.getPresentation()); return this; } /** * Add description to javadoc section. * * @param descriptions the Descriptions * @return the Java doc builder */ public JavaDocBuilder addDescription(List<String> descriptions) { Iterator<String> iterator = descriptions.iterator(); while (iterator.hasNext()) { String description = iterator.next(); if (isAcceptedDescription(description, iterator.hasNext())) { builder.append(description); if (StringUtils.contains(description, JavaDocElements.NEW_LINE.getPresentation())) { builder.append(JavaDocElements.LINE_START.getPresentation()); } } } return this; } /** * Add tag description to javadoc section. * * @param descriptions the Descriptions * @return the Java doc builder */ public JavaDocBuilder addTagDescription(List<String> descriptions) { for (int i = 0; i < descriptions.size(); i++) { String description = descriptions.get(i); if (StringUtils.isNotBlank(description)) { if (i != 0) { addNewLine(); } builder.append(description); } } return this; } /** * Add tag to javadoc section. * * @param name the Name * @param tag the Tag * @return the Java doc builder */ public JavaDocBuilder addTag(String name, JavaDocTag tag) { builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); builder.append(JavaDocElements.TAG_START.getPresentation()); builder.append(name); builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); if (StringUtils.isNotBlank(tag.getRefParam())) { builder.append(tag.getRefParam()); } else if (StringUtils.isNotBlank(tag.getValue())) { builder.append(tag.getValue()); } builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); addTagDescription(tag.getDescription()); return this; } /** * Add tags to javadoc section. * * @param tags the Tags * @return the Java doc builder */ public JavaDocBuilder addTags(@NotNull Map<String, List<JavaDocTag>> tags) { Iterator<Entry<String, List<JavaDocTag>>> iterator = tags.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, List<JavaDocTag>> entry = iterator.next(); String name = entry.getKey(); Iterator<JavaDocTag> javaDocTagsIterator = entry.getValue().iterator(); while (javaDocTagsIterator.hasNext()) { JavaDocTag javaDocTag = javaDocTagsIterator.next(); addTag(name, javaDocTag); if (javaDocTagsIterator.hasNext()) { addNewLine(); } } if (iterator.hasNext()) { addNewLine(); } } return this; } /** * Creates the java doc by default rules. * * @param javadoc the Javadoc * @return the Java doc builder */ public JavaDocBuilder createDefaultJavaDoc(@NotNull JavaDoc javadoc) { openJavaDoc(); addDescription(javadoc.getDescription()); addTags(javadoc.getTags()); closeJavaDoc(); return this; } /** * Builds the javadoc section. * * @return the String */ @NotNull public String build() { return builder.toString(); } private boolean closeRegularJavaDoc() { boolean result = false; if (builder.lastIndexOf(JavaDocElements.LINE_START.getPresentation()) != builder.length() - 1 && builder.lastIndexOf(JavaDocElements.NEW_LINE.getPresentation()) >= 0) { builder.append(JavaDocElements.NEW_LINE.getPresentation()); builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); builder.append(JavaDocElements.LINE_START.getPresentation()); result = true; } return result; } private boolean closeOneLineJavaDoc() { boolean result = false; if (builder.indexOf(JavaDocElements.NEW_LINE.getPresentation()) < 0) { builder.append(JavaDocElements.LINE_START.getPresentation()); result = true; } return result; } private boolean isAcceptedDescription(String description, boolean hasNext) { boolean result = false; // add any not empty string (it could be blank), but do not add last string if this is a space if ((hasNext && StringUtils.isNotEmpty(description)) || (!hasNext && !description.matches(" +"))) { result = true; } return result; } }