21
21
import java .nio .ByteBuffer ;
22
22
import java .nio .channels .ServerSocketChannel ;
23
23
import java .nio .channels .SocketChannel ;
24
- import java .nio .file .Path ;
25
24
import java .nio .file .Paths ;
26
- import java .util .HashMap ;
27
- import java .util .Map ;
28
- import java .util .Objects ;
29
- import java .util .StringJoiner ;
30
25
import java .util .concurrent .atomic .AtomicBoolean ;
31
- import java .util .function .Consumer ;
32
26
33
27
import javax .inject .Named ;
34
28
import javax .inject .Singleton ;
35
29
36
- import org .apache .maven .eventspy . EventSpy ;
37
- import org .apache .maven .execution . ExecutionEvent ;
30
+ import org .apache .maven .AbstractMavenLifecycleParticipant ;
31
+ import org .apache .maven .MavenExecutionException ;
38
32
import org .apache .maven .execution .ExecutionEvent .Type ;
39
- import org .apache .maven .project . MavenProject ;
33
+ import org .apache .maven .execution . MavenSession ;
40
34
import org .slf4j .Logger ;
41
35
import org .slf4j .LoggerFactory ;
42
36
43
37
/**
44
- * This {@link EventSpy} listens to certain events within a Maven build JVM and
45
- * sends certain data (e.g. about projects being built) to the JVM of the
46
- * Eclipse IDE that launched the Maven build JVM.
47
- *
48
- * @author Hannes Wellmann
49
- *
38
+ * Bridge between the remote running maven and the local m2e to exchange event
39
+ * messages and information.
50
40
*/
51
- @ Named
41
+ @ Named ( "m2e" )
52
42
@ Singleton
53
- public class M2EMavenBuildDataBridge implements EventSpy {
43
+ public class M2EMavenBuildDataBridge extends AbstractMavenLifecycleParticipant {
54
44
55
45
private static final String SOCKET_FILE_PROPERTY_NAME = "m2e.build.project.data.socket.port" ;
56
46
private static final String DATA_SET_SEPARATOR = ";;" ;
@@ -60,7 +50,7 @@ public class M2EMavenBuildDataBridge implements EventSpy {
60
50
private SocketChannel writeChannel ;
61
51
62
52
@ Override
63
- public void init ( Context context ) throws IOException {
53
+ public void afterSessionStart ( MavenSession session ) throws MavenExecutionException {
64
54
String socketPort = System .getProperty (SOCKET_FILE_PROPERTY_NAME );
65
55
if (socketPort != null ) {
66
56
try {
@@ -76,81 +66,38 @@ public void init(Context context) throws IOException {
76
66
}
77
67
78
68
@ Override
79
- public void close () throws IOException {
80
- writeChannel .close ();
69
+ public void afterSessionEnd (MavenSession session ) throws MavenExecutionException {
70
+ try {
71
+ writeChannel .close ();
72
+ } catch (IOException e ) {
73
+ // we can't do much here anyways...
74
+ }
81
75
}
82
76
83
- @ Override
84
- public void onEvent (Object event ) throws Exception {
85
- if (writeChannel != null && event instanceof ExecutionEvent
86
- && ((ExecutionEvent ) event ).getType () == Type .ProjectStarted ) {
87
-
88
- String message = serializeProjectData (((ExecutionEvent ) event ).getProject ());
77
+ boolean isActive () {
78
+ return writeChannel != null ;
79
+ }
89
80
90
- ByteBuffer buffer = ByteBuffer .wrap (message .getBytes ());
91
- synchronized (writeChannel ) {
81
+ void sendMessage (String msg ) {
82
+ SocketChannel channel = writeChannel ;
83
+ if (channel != null ) {
84
+ ByteBuffer buffer = ByteBuffer .wrap ((msg + DATA_SET_SEPARATOR ).getBytes ());
85
+ synchronized (channel ) {
92
86
while (buffer .hasRemaining ()) {
93
- writeChannel .write (buffer );
87
+ try {
88
+ channel .write (buffer );
89
+ } catch (IOException e ) {
90
+ LOGGER .warn ("Can't forward message to m2e: " + e );
91
+ }
94
92
}
95
93
}
96
94
}
97
95
}
98
96
99
- private static String serializeProjectData (MavenProject project ) {
100
- StringJoiner data = new StringJoiner ("," );
101
- add (data , "groupId" , project .getGroupId ());
102
- add (data , "artifactId" , project .getArtifactId ());
103
- add (data , "version" , project .getVersion ());
104
- add (data , "file" , project .getFile ());
105
- add (data , "basedir" , project .getBasedir ());
106
- add (data , "build.directory" , project .getBuild ().getDirectory ());
107
- return data .toString () + DATA_SET_SEPARATOR ;
108
- }
109
97
110
- private static void add (StringJoiner data , String key , Object value ) {
111
- data .add (key + "=" + value );
112
- }
113
98
114
- /**
115
- * <p>
116
- * This method is supposed to be called from M2E within the Eclipse-IDE JVM.
117
- * </p>
118
- *
119
- * @param dataSet the data-set to parse
120
- * @return the {@link MavenProjectBuildData} parsed from the given string
121
- */
122
- private static MavenProjectBuildData parseMavenBuildProject (String dataSet ) {
123
- Map <String , String > data = new HashMap <>(8 );
124
- for (String entry : dataSet .split ("," )) {
125
- String [] keyValue = entry .split ("=" );
126
- if (keyValue .length != 2 ) {
127
- throw new IllegalStateException ("Invalid data-set format" + dataSet );
128
- }
129
- data .put (keyValue [0 ], keyValue [1 ]);
130
- }
131
- return new MavenProjectBuildData (data );
132
- }
133
99
134
- public static final class MavenProjectBuildData {
135
- public final String groupId ;
136
- public final String artifactId ;
137
- public final String version ;
138
- public final Path projectBasedir ;
139
- public final Path projectFile ;
140
- public final Path projectBuildDirectory ;
141
-
142
- MavenProjectBuildData (Map <String , String > data ) {
143
- if (data .size () != 6 ) {
144
- throw new IllegalArgumentException ();
145
- }
146
- this .groupId = Objects .requireNonNull (data .get ("groupId" ));
147
- this .artifactId = Objects .requireNonNull (data .get ("artifactId" ));
148
- this .version = Objects .requireNonNull (data .get ("version" ));
149
- this .projectBasedir = Paths .get (data .get ("basedir" ));
150
- this .projectFile = Paths .get (data .get ("file" ));
151
- this .projectBuildDirectory = Paths .get (data .get ("build.directory" ));
152
- }
153
- }
100
+
154
101
155
102
/**
156
103
* Prepares the connection to a {@code Maven build JVM} to be launched and is
@@ -163,7 +110,7 @@ public static final class MavenProjectBuildData {
163
110
* @return the preapre {@link MavenBuildConnection}
164
111
* @throws IOException
165
112
*/
166
- public static MavenBuildConnection prepareConnection (String label , Consumer < MavenProjectBuildData > datasetListener )
113
+ public static MavenBuildConnection prepareConnection (String label , MavenBuildListener datasetListener )
167
114
throws IOException {
168
115
169
116
// TODO: use UNIX domain socket once Java-17 is required by Maven
@@ -187,9 +134,21 @@ public static MavenBuildConnection prepareConnection(String label, Consumer<Mave
187
134
for (int terminatorIndex ; (terminatorIndex = message .indexOf (DATA_SET_SEPARATOR )) >= 0 ;) {
188
135
String dataSet = message .substring (0 , terminatorIndex );
189
136
message .delete (0 , terminatorIndex + DATA_SET_SEPARATOR .length ());
190
-
191
- MavenProjectBuildData buildData = parseMavenBuildProject (dataSet );
192
- datasetListener .accept (buildData );
137
+ if (dataSet .startsWith (M2eEventSpy .PROJECT_START_EVENT )) {
138
+ MavenProjectBuildData buildData = MavenProjectBuildData
139
+ .parseMavenBuildProject (
140
+ dataSet .substring (M2eEventSpy .PROJECT_START_EVENT .length ()));
141
+ datasetListener .projectStarted (buildData );
142
+ } else if (dataSet .startsWith (M2eMojoExecutionListener .TEST_START_EVENT )) {
143
+ String path = dataSet .substring (M2eMojoExecutionListener .TEST_START_EVENT .length ());
144
+ datasetListener .onTestEvent (new MavenTestEvent (Type .MojoStarted , Paths .get (path )));
145
+ } else if (dataSet .startsWith (M2eMojoExecutionListener .TEST_END_EVENT )) {
146
+ String path = dataSet .substring (M2eMojoExecutionListener .TEST_END_EVENT .length ());
147
+ datasetListener .onTestEvent (new MavenTestEvent (Type .MojoSucceeded , Paths .get (path )));
148
+ } else if (dataSet .startsWith (M2eMojoExecutionListener .TEST_END_FAILED_EVENT )) {
149
+ String path = dataSet .substring (M2eMojoExecutionListener .TEST_END_EVENT .length ());
150
+ datasetListener .onTestEvent (new MavenTestEvent (Type .MojoFailed , Paths .get (path )));
151
+ }
193
152
}
194
153
// Explicit cast for compatibility with covariant return type on JDK 9's
195
154
// ByteBuffer
0 commit comments