Skip to content

Commit

Permalink
Bug fix (#1)
Browse files Browse the repository at this point in the history
Fixed keyboard Short Cut.
Provided room for viewing generated code for in pop up for already existing classes.
File chooser is restricted to current project modules.
  • Loading branch information
VISHNUVISHAL11 authored Jan 6, 2023
1 parent d38e032 commit 2cffb8a
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 49 deletions.
Binary file added Documents/imageCheckBox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ Import the downloaded jar from disk. <br>

## How to Use The Plugin
- Select the xml code.
- press Shift + ` shortcut and provide the details.
- Code will be generated at the specified location.
- press Ctrl + Shift + ` shortcut and provide the details.
- Code will be generated at the specified location.<br>

![imageCheckBox](Documents/imageCheckBox.png "imageCheckBox")
- Uncheck the checkBok to avoid writing and just view the generated code in pop up.
- Go to action by pressing (⌘+Shift+A or Ctrl+Shift+A) and change the shortcut by yourself.

![GIF](Documents/MapStructGIF.gif "GIF")

## Support

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ application {
}

group = "com.techconative"
version = "1.0-SNAPSHOT"
version = "0.0.2"

repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.JBUI;
import com.techconative.actions.service.GenerateMappings;
Expand All @@ -21,7 +23,11 @@
import javax.swing.text.StyleConstants;
import java.awt.*;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


public class DozerTOMapperStructPlugin extends AnAction {
Expand All @@ -31,17 +37,41 @@ public void actionPerformed(@NotNull AnActionEvent e) {
Editor ediTorRequiredData = e.getRequiredData(CommonDataKeys.EDITOR);
CaretModel caretModel = ediTorRequiredData.getCaretModel();
String selectedText = caretModel.getCurrentCaret().getSelectedText();

FileChooserDescriptor fileChooserDescriptor =
new FileChooserDescriptor(false, true, false,
false, false, false);
FileChooser.chooseFile(fileChooserDescriptor, e.getProject(), null, consumer -> {
JTextPanes(consumer.toNioPath().normalize().toString(), selectedText);
if (selectedText == null || selectedText.equals("") || selectedText.equals(" ")) {
return;
}
if (GenerateMappings.CheckXml(selectedText)){
String code = null;
try {
code = GenerateMappings.generateMappings(selectedText, "path",
false, "className", "attributeName");
} catch (IOException | BadLocationException ex) {
return;
}
if (code != null) {
try {
getJTextPlane(code);
} catch (BadLocationException ex) {
return;
}
);
}
}else {

FileChooserDescriptor fileChooserDescriptor =
new FileChooserDescriptor(false, true, false,
false, false, false);
List<VirtualFile> virtualFiles= Arrays.stream(ProjectRootManager.getInstance(e.getProject()).getContentSourceRoots()).filter(
x->(x.toNioPath().normalize().toString().replace(FileSystems.getDefault().getSeparator(),".").contains("src.main.java"))
).collect(Collectors.toList());
fileChooserDescriptor.setRoots(virtualFiles);
FileChooser.chooseFile(fileChooserDescriptor, e.getProject(), null, consumer -> {
JTextPanes(consumer.toNioPath().normalize().toString(), selectedText);
}
);
}
}

JTextPane getJTextPlane(String code) throws BadLocationException {
public static JTextPane getJTextPlane(String code) throws BadLocationException {
JFrame frame = new JFrame("GENERATED CODE");
Container cp = frame.getContentPane();
JTextPane pane = new JTextPane();
Expand Down Expand Up @@ -117,8 +147,10 @@ void JTextPanes(String path, String selectedText) {
if (isSelected) {
GenerateMappings.generateMappings(selectedText, path, true, className, attributeName);
} else {
getJTextPlane(GenerateMappings.generateMappings(selectedText, path,
false, className, attributeName));
String code = GenerateMappings.generateMappings(selectedText, path,
false, className, attributeName);
if (code != null)
getJTextPlane(code);
}
} catch (IOException | BadLocationException ex) {
Messages.showMessageDialog(String.valueOf(ex), "ERROR", Messages.getErrorIcon());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.intellij.openapi.ui.Messages;
import com.squareup.javapoet.*;
import com.techconative.actions.DozerTOMapperStructPlugin;
import com.techconative.actions.utilities.Utilities;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
Expand All @@ -14,50 +15,73 @@
import org.xml.sax.SAXException;

import javax.lang.model.element.Modifier;
import javax.swing.text.BadLocationException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.IntStream;

public class GenerateMappings {

static private TypeSpec.Builder person;
static private boolean alreadyExecuted = false;
private static Document finalDocument;
private static int length;

public static String generateMappings(String selectedText, String path, boolean generate,
String className, String mapperName) throws IOException {

public static Integer check(String selectedText) {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
Map<String, String> map = new HashMap<>();
DocumentBuilder dBuilder = null;
length = 0;
try {
dBuilder = dbFactory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
Messages.showMessageDialog(String.valueOf(ex), "ERROR", Messages.getErrorIcon());
return null;
return 0;
}
finalDocument = null;
try {
finalDocument = dBuilder.parse(new InputSource(new StringReader(selectedText)));
} catch (SAXException | IOException | NullPointerException ex) {
Messages.showMessageDialog(String.valueOf(ex), "ERROR", Messages.getErrorIcon());
return null;
return 0;
}
finalDocument.getDocumentElement().normalize();
return finalDocument.getElementsByTagName("mapping").getLength();
}

int length = finalDocument.getElementsByTagName("mapping").getLength();
public static boolean CheckXml(String selectedText) {
length = check(selectedText);
if (length == 1 && finalDocument.getElementsByTagName("mappings").getLength() == 0) {
alreadyExecuted = true;
return true;
} else {
alreadyExecuted = false;
return false;
}
}

public static String generateMappings(String selectedText, String path, boolean generate,
String className, String mapperName) throws IOException, BadLocationException {
if (length == 0) {
return null;
}
Map<String, String> map = new HashMap<>();
person = null;
AtomicBoolean partialMapping = new AtomicBoolean(false);

if (length != finalDocument.getElementsByTagName("class-a").getLength() &&
length != finalDocument.getElementsByTagName("class-b").getLength()) {
Messages.showMessageDialog("Wrong xml structure", "ERROR", Messages.getErrorIcon());
return null;
}


IntStream.range(0, length).forEachOrdered(x -> {
map.clear();
NodeList nodeList = finalDocument.getElementsByTagName("mapping").item(x).getChildNodes();
Expand Down Expand Up @@ -99,13 +123,26 @@ public static String generateMappings(String selectedText, String path, boolean
if (finalDocument.getElementsByTagName("mapping").item(x).getAttributes().getNamedItem("map-id") != null) {
String mapId = finalDocument.getElementsByTagName("mapping").item(x).getAttributes()
.getNamedItem("map-id").getTextContent();
person.addAnnotation(AnnotationSpec.builder(Named.class)
.addMember("value", "$S", Utilities.apply(mapId)).build());
map.put("methodMapId", mapId);
}
if (finalDocument.getElementsByTagName("mappings").getLength() == 0 && length >= 1 && !generate) {
try {
DozerTOMapperStructPlugin.getJTextPlane(generateMethod(map, annotationSpecList, true)
.replaceAll("@org.mapstruct.", "@"));
partialMapping.set(true);
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
} else {
generateMethod(map, annotationSpecList, false);
}
generateMethod(map, annotationSpecList);
});

return generateJavaClass(path, generate);
if (partialMapping.get()) {
alreadyExecuted = false;
return null;
} else {
return generateJavaClass(path, generate);
}
}


Expand All @@ -119,7 +156,7 @@ private static String getClassName(String value) {
return strings[strings.length - 1];
}

static void generateMethod(Map<String, String> map, List<AnnotationSpec> annotationSpecList) {
static String generateMethod(Map<String, String> map, List<AnnotationSpec> annotationSpecList, boolean partialMapping) {

ClassName classTypeB = ClassName.get(map.get("packageB"), map.get("ClassBName"));
ClassName classTypeA = ClassName.get(map.get("packageA"), map.get("ClassAName"));
Expand All @@ -128,16 +165,24 @@ static void generateMethod(Map<String, String> map, List<AnnotationSpec> annotat
.methodBuilder("to" + map.get("ClassBName"))
.addParameter(classTypeA, Utilities.getObjectNameForClassName(map.get("ClassAName")))
.returns(classTypeB).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT);
AnnotationSpec.Builder anno = AnnotationSpec.builder(Mappings.class);
IntStream.range(0, annotationSpecList.size()).forEachOrdered(x ->
anno.addMember("value", "$L", annotationSpecList.get(x))
);
method.addAnnotation(anno.build());
if (!annotationSpecList.isEmpty() && annotationSpecList != null) {
AnnotationSpec.Builder anno = AnnotationSpec.builder(Mappings.class);
IntStream.range(0, annotationSpecList.size()).forEachOrdered(x ->
anno.addMember("value", "$L", annotationSpecList.get(x))
);
method.addAnnotation(anno.build());
}
if (map.containsKey("methodMapId")) {
method.addAnnotation(AnnotationSpec.builder(Named.class)
.addMember("value", "$S", Utilities.findAndApply(map.get("methodMapId"))).build());
}
person.addMethod(method.build());
if (partialMapping) {
return method.build().toString().replaceAll(map.get("packageB") + ".", "")
.replaceAll(map.get("packageA") + ".", "");
} else {
person.addMethod(method.build());
return null;
}
}

static private void buildJavaClass(String path, Map<String, String> map, String className, String mapperName) {
Expand Down Expand Up @@ -177,10 +222,12 @@ static private String generateJavaClass(String path, boolean generate) throws IO
return code;
}

static private String[] getPath(String path) {
String str = path.replace(path.charAt(2), '.');
String[] strings = str.split("src.main.java.");
strings[0] = str.replaceAll("." + strings[1], "").trim().replace('.', path.charAt(2));
private static String[] getPath(String path) {
String fileSeparator = FileSystems.getDefault().getSeparator();
String str = path.replace(fileSeparator, ".");
String[] strings = new String[2];
strings[1] = str.split(".src.main.java.")[1];
strings[0] = path.replace(strings[1].replace(".", fileSeparator), "");
return strings;
}

Expand Down
15 changes: 6 additions & 9 deletions src/main/java/com/techconative/actions/test/Test.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.techconative.actions.test;


import com.techconative.actions.service.GenerateMappings;

import javax.swing.text.BadLocationException;
import java.io.IOException;


public class Test {
public static void main(String[] args) throws IOException {
public static void main(String[] args) throws IOException, BadLocationException {
Test test=new Test();
test.run();
}
void run() throws IOException {
void run() throws IOException, BadLocationException {
String xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<mappings>\n" +
" <mapping type=\"one-way\" map-id=\"Custom_Map\">\n" +
Expand Down Expand Up @@ -48,10 +47,8 @@ void run() throws IOException {
" </mapping>\n" +
"\n" +
"</mappings>";
GenerateMappings.generateMappings(xml,"C:\\Users\\VISHNU\\Documents\\GitHub\\plugin\\src\\main\\java\\com\\techconative\\actions\\mappers",false,"className","mapper");
GenerateMappings.generateMappings(xml,"C:\\Users\\VISHNU\\Documents\\GitHub\\plugin\\src\\main\\java\\com\\techconative\\actions\\mappers",true,"className","mapper");


// GenerateMappings.generateMappings(xml, "<GIve complete absolute path>",false,"className","mapper");
// GenerateMappings.generateMappings(xml,"<GIve complete absolute path>",true,"className","mapper");
}

}
39 changes: 36 additions & 3 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,45 @@
<!-- A displayed Vendor name or Organization ID displayed on the Plugins Page. -->
<vendor email="[email protected]" url="https://www.techconative.com">TechConative</vendor>

<change-notes>><![CDATA[
<b>How to Use The Plugin</b><br>
- Select the xml code.<br>
- press Ctrl + Shift + ` shortcut and provide the details.<br>
- Code will be generated at the specified location.<br>
- Can run in any platform independent of OS.
- Can just view generated code without writing.
- Can get code in pop up for already created class and append the missing part.
- you can go to action by pressing (⌘+Shift+A or Ctrl+Shift+A) and type plugin name and change the shortcut yourself.
]]>
</change-notes>

<!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager.
Simple HTML elements (text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag.
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-description -->
<description><![CDATA[
Here is my short description for My GenerateMappings plugin.<br>
<em>Generate</em>
This is a productivity tool to be used when you're modernizing you're moving the mappings from Dozer to Mapstruct in your applications.
With this plugin,
<ol>
<li>Select your <i>&lt;mapper&gt;</i>, <i>&lt;mappers&gt;</i> mapper definitions.</li>
<li>Press shortcut to generate equivalent Mapstruct definitions in seconds.</li>
</ol>
What this solves,
<ul>
<li>Straight forward mapping definitions with fields and ignore fields.</li>
<li>Mapid.</li>
</ul>
We'll be covering more cases of mapping in upcoming releases.
Feel free to contribute to the <a href="https://github.com/techconative/DoStruct-plugin/tree/bugFix">source code</href>
<em>With love from <a href="https://techconative.com/">TechConative<a> ❤️</em>
]]></description>

<!-- Product and plugin compatibility requirements.
Expand All @@ -32,7 +65,7 @@
<action id="com.techconative.actions.DozerTOMapperStructPlugin" class="com.techconative.actions.DozerTOMapperStructPlugin"
text="DozerTOMapperStructPlugin" description="DozerTOMapperStructPlugin">
<add-to-group group-id="CodeCompletionGroup" anchor="last"/>
<keyboard-shortcut keymap="$default" first-keystroke="shift BACK_QUOTE"/>
<keyboard-shortcut keymap="$default" first-keystroke="shift ctrl BACK_QUOTE"/>
</action>
</actions>
</idea-plugin>
9 changes: 9 additions & 0 deletions src/main/resources/icons/PluginFireIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2cffb8a

Please sign in to comment.