11package net .servicestack .idea ;
22
3+ import com .intellij .openapi .application .ApplicationManager ;
4+ import com .intellij .openapi .application .Result ;
5+ import com .intellij .openapi .command .WriteCommandAction ;
6+ import com .intellij .openapi .editor .DocumentRunnable ;
7+ import com .intellij .openapi .fileEditor .FileDocumentManager ;
38import com .intellij .openapi .module .Module ;
9+ import com .intellij .openapi .project .Project ;
10+ import com .intellij .openapi .vfs .LocalFileSystem ;
11+ import com .intellij .openapi .vfs .VirtualFile ;
12+ import com .intellij .openapi .vfs .VirtualFileManager ;
13+ import com .intellij .psi .PsiDocumentManager ;
14+ import com .intellij .psi .PsiElement ;
415import com .intellij .psi .PsiFile ;
16+ import com .intellij .psi .codeStyle .CodeStyleManager ;
17+ import com .intellij .psi .impl .source .codeStyle .CodeEditUtil ;
518import com .intellij .psi .search .FilenameIndex ;
619import com .intellij .psi .search .GlobalSearchScope ;
7- import org .apache .maven .model .Dependency ;
8- import org .apache .maven .model .Model ;
9- import org .apache .maven .model .io .xpp3 .MavenXpp3Reader ;
10- import org .apache .maven .model .io .xpp3 .MavenXpp3Writer ;
11- import org .codehaus .plexus .util .xml .pull .XmlPullParserException ;
20+ import com .intellij .util .xml .GenericDomValue ;
21+ import org .jetbrains .annotations .NotNull ;
22+ import org .w3c .dom .Document ;
23+ import org .w3c .dom .Node ;
24+ import org .w3c .dom .NodeList ;
25+ import org .xml .sax .SAXException ;
1226
27+ import javax .xml .parsers .DocumentBuilder ;
28+ import javax .xml .parsers .DocumentBuilderFactory ;
29+ import javax .xml .parsers .ParserConfigurationException ;
30+ import javax .xml .transform .OutputKeys ;
31+ import javax .xml .transform .Transformer ;
32+ import javax .xml .transform .TransformerException ;
33+ import javax .xml .transform .TransformerFactory ;
34+ import javax .xml .transform .dom .DOMSource ;
35+ import javax .xml .transform .stream .StreamResult ;
1336import java .io .File ;
14- import java .io .FileReader ;
15- import java .io .FileWriter ;
1637import java .io .IOException ;
17- import java .util .List ;
18-
19- /**
20- * Created by Layoric on 10/05/2015.
21- */
22- public class IDEAPomFileHelper implements IPomFileHelper {
23- @ Override
24- public boolean addMavenDependencyIfRequired (File pomFile , String groupId , String packageId , String version ) throws Exception {
25- boolean noDependencyAdded = true ;
26- MavenXpp3Reader reader = new MavenXpp3Reader ();
27- Model pomModel ;
28- try {
29- pomModel = reader .read (new FileReader (pomFile ));
30- final List <Dependency > dependencies = pomModel .getDependencies ();
31- boolean requiresPomDependency = true ;
32- for (Dependency dep : dependencies ) {
33- if (dep .getGroupId ().equals (groupId ) && dep .getArtifactId ().equals (packageId )) {
34- requiresPomDependency = false ;
35- }
36- }
38+ import java .io .StringWriter ;
3739
38- if (requiresPomDependency ) {
39- Dependency dependency = new Dependency ();
40- dependency .setGroupId (groupId );
41- dependency .setArtifactId (packageId );
42- dependency .setVersion (version );
43- FileWriter writer = new FileWriter (pomFile .getAbsolutePath ());
44- pomModel .addDependency (dependency );
45- new MavenXpp3Writer ().write (writer , pomModel );
46- noDependencyAdded = false ;
47- }
40+ public class IDEAPomFileHelper {
4841
42+ public boolean addMavenDependency (final Module module ,File pomFile , String groupId , String packageId , String version ) throws Exception {
43+ boolean dependencyAdded = false ;
44+
45+ try {
46+ if (!pomHasMavenDependency (pomFile ,groupId ,packageId ,version )) {
47+ PomAppendDependency (module , pomFile ,groupId ,packageId ,version );
48+ dependencyAdded = true ;
49+ }
4950 } catch (IOException e ) {
5051 e .printStackTrace ();
5152 throw new Exception ("Unable to process pom.xml to add " + groupId + ":" + packageId + ":" + version );
52- } catch (XmlPullParserException e ) {
53+ } catch (ParserConfigurationException e ) {
5354 e .printStackTrace ();
5455 throw new Exception ("Unable to process pom.xml to add " + groupId + ":" + packageId + ":" + version );
5556 }
56- return noDependencyAdded ;
57+
58+ return dependencyAdded ;
5759 }
5860
59- @ Override
61+
6062 public String findNearestModulePomFile (Module module ) {
6163 PsiFile [] pomLibFiles = FilenameIndex .getFilesByName (module .getProject (), "pom.xml" , GlobalSearchScope .allScope (module .getProject ()));
6264 String pomFilePath = null ;
@@ -67,4 +69,117 @@ public String findNearestModulePomFile(Module module) {
6769 }
6870 return pomFilePath ;
6971 }
72+
73+ private void PomAppendDependency (final Module module , final File pomFile , String groupId , String packageId , String version ) throws ParserConfigurationException , IOException , SAXException , TransformerException {
74+ DocumentBuilderFactory docFactory = DocumentBuilderFactory .newInstance ();
75+ DocumentBuilder docBuilder = docFactory .newDocumentBuilder ();
76+ final Document doc = docBuilder .parse (pomFile );
77+ Node root = doc .getFirstChild ();
78+
79+ if (!pomHasDependenciesNode (doc )) {
80+ root .appendChild (doc .createElement ("dependencies" ));
81+ }
82+
83+ Node dependenciesNode = getMavenDependenciesNode (doc );
84+ Node newDepNode = doc .createElement ("dependency" );
85+ Node groupNode = doc .createElement ("groupId" );
86+ groupNode .appendChild (doc .createTextNode (groupId ));
87+ Node artifactNode = doc .createElement ("artifactId" );
88+ artifactNode .appendChild (doc .createTextNode (packageId ));
89+ Node versionNode = doc .createElement ("version" );
90+ versionNode .appendChild (doc .createTextNode (version ));
91+ newDepNode .appendChild (groupNode );
92+ newDepNode .appendChild (artifactNode );
93+ newDepNode .appendChild (versionNode );
94+ dependenciesNode .appendChild (newDepNode );
95+
96+ TransformerFactory transformerFactory = TransformerFactory .newInstance ();
97+ Transformer transformer = transformerFactory .newTransformer ();
98+ transformer .setOutputProperty (OutputKeys .INDENT , "yes" );
99+ transformer .setOutputProperty ("{http://xml.apache.org/xslt}indent-amount" , "2" );
100+
101+ final StringWriter writer = new StringWriter ();
102+ transformer .transform (new DOMSource (doc ), new StreamResult (writer ));
103+
104+ final Project project = module .getProject ();
105+ final VirtualFile virtualFile = LocalFileSystem .getInstance ().findFileByIoFile (pomFile );
106+ final com .intellij .openapi .editor .Document document = FileDocumentManager .getInstance ().getDocument (virtualFile );
107+ final PsiFile psiPomFile = PsiDocumentManager .getInstance (project ).getPsiFile (document );
108+ final FileDocumentManager fileDocumentManager = FileDocumentManager .getInstance ();
109+ fileDocumentManager .saveDocument (document ); //when file is edited and editor is closed, it is needed to save the text
110+ PsiDocumentManager .getInstance (project ).commitDocument (document );
111+ PsiDocumentManager .getInstance (module .getProject ()).commitAllDocuments ();
112+ ApplicationManager .getApplication ().runWriteAction (new DocumentRunnable (document , null ) {
113+ @ Override public void run () {
114+ PsiDocumentManager .getInstance (module .getProject ())
115+ .doPostponedOperationsAndUnblockDocument (document );
116+ document .setText (writer .getBuffer ().toString ().replaceAll ("\r \n " ,"\n " ));
117+ fileDocumentManager .saveDocument (document );
118+ PsiDocumentManager .getInstance (project ).commitDocument (document );
119+ }
120+ });
121+ }
122+
123+ private boolean pomHasDependenciesNode (Document document ) {
124+ return getMavenDependenciesNode (document ) != null ;
125+ }
126+
127+ private Node getMavenDependenciesNode (Document document ) {
128+ Node rootNode = document .getFirstChild ();
129+ NodeList firstChildern = rootNode .getChildNodes ();
130+ Node result = null ;
131+ for (int i = 0 ; i < firstChildern .getLength (); i ++) {
132+ Node child = firstChildern .item (i );
133+ if (child == null ) {
134+ continue ;
135+ }
136+ if (child .getNodeName ().equals ("dependencies" )) {
137+ result = child ;
138+ break ;
139+ }
140+ }
141+ return result ;
142+ }
143+
144+ private boolean pomHasMavenDependency (File pomFile , String groupId , String packageId , String version ) throws ParserConfigurationException , IOException , SAXException {
145+ boolean hasDependency = false ;
146+ DocumentBuilderFactory docFactory = DocumentBuilderFactory .newInstance ();
147+ DocumentBuilder docBuilder = docFactory .newDocumentBuilder ();
148+ Document doc = docBuilder .parse (pomFile );
149+
150+ if (!pomHasDependenciesNode (doc )) {
151+ return false ;
152+ }
153+
154+ Node dependencies = getMavenDependenciesNode (doc );
155+ NodeList depElements = dependencies .getChildNodes ();
156+ for (int i = 0 ; i < depElements .getLength (); i ++) {
157+ Node dependencyElement = depElements .item (i );
158+ if (pomDependencyElementMatch (dependencyElement , groupId ,packageId ,version )) {
159+ hasDependency = true ;
160+ break ;
161+ }
162+ }
163+ return hasDependency ;
164+ }
165+
166+ private boolean pomDependencyElementMatch (Node dependencyElement , String groupId , String packageId , String version ) {
167+ boolean groupIdMatch = false ;
168+ boolean artifactIdMatch = false ;
169+ boolean versionMatch = false ;
170+ NodeList dependencyProperties = dependencyElement .getChildNodes ();
171+ for (int j = 0 ; j < dependencyProperties .getLength (); j ++) {
172+ Node depProp = dependencyProperties .item (j );
173+ if (depProp .getNodeName ().equals ("groupId" ) && depProp .getNodeValue ().equals (groupId )) {
174+ groupIdMatch = true ;
175+ }
176+ if (depProp .getNodeName ().equals ("artifactId" ) && depProp .getNodeValue ().equals (packageId )) {
177+ artifactIdMatch = true ;
178+ }
179+ if (depProp .getNodeName ().equals ("version" ) && depProp .getNodeValue ().equals (version )) {
180+ versionMatch = true ;
181+ }
182+ }
183+ return groupIdMatch && artifactIdMatch && versionMatch ;
184+ }
70185}
0 commit comments