Skip to content

Commit 4c2460f

Browse files
committed
implemented receiving classpath from IDEA.
1 parent c2d7b2c commit 4c2460f

8 files changed

Lines changed: 284 additions & 28 deletions

src/main/java/com/ss/editor/Editor.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import com.ss.editor.executor.impl.JMEThreadExecutor;
4141
import com.ss.editor.extension.loader.SceneLoader;
4242
import com.ss.editor.manager.ExecutorManager;
43-
import com.ss.editor.manager.InitializationManager;
4443
import com.ss.editor.manager.WorkspaceManager;
4544
import com.ss.editor.ui.event.FXEventManager;
4645
import com.ss.editor.ui.event.impl.WindowChangeFocusEvent;
@@ -336,9 +335,6 @@ public void simpleInitApp() {
336335
createLightProbes();
337336
stateManager.detach(stateManager.getState(DebugKeysAppState.class));
338337

339-
final InitializationManager initializationManager = InitializationManager.getInstance();
340-
initializationManager.onAfterCreateJMEContext();
341-
342338
new EditorThread(new ThreadGroup("JavaFX"), JFXApplication::start, "JavaFX Launch").start();
343339
}
344340

src/main/java/com/ss/editor/manager/ClasspathManager.java

Lines changed: 153 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ public class ClasspathManager {
3636
public enum Scope {
3737
CORE,
3838
CUSTOM,
39-
PLUGINS,;
39+
PLUGINS,
40+
LOCAL_LIBRARIES,
41+
LOCAL_CLASSES;
4042

4143
@NotNull
4244
public static final Set<Scope> ONLY_CORE = EnumSet.of(CORE);
@@ -83,6 +85,18 @@ public static ClasspathManager getInstance() {
8385
@Nullable
8486
private volatile ClassPathScanner customScanner;
8587

88+
/**
89+
* The local libraries scanner.
90+
*/
91+
@Nullable
92+
private volatile ClassPathScanner localLibrariesScanner;
93+
94+
/**
95+
* The local classes scanner.
96+
*/
97+
@Nullable
98+
private volatile ClassPathScanner localClassesScanner;
99+
86100
/**
87101
* The libraries class loader.
88102
*/
@@ -151,16 +165,16 @@ public synchronized void reload() {
151165

152166
final URLClassLoader librariesLoader = getLibrariesLoader();
153167
final URLClassLoader classesLoader = getClassesLoader();
154-
final ClassLoader classLoader = classesLoader == null ? librariesLoader : classesLoader;
155-
156-
final ClassPathScanner scanner = classesLoader == null ? ClassPathScannerFactory.newDefaultScanner() :
157-
ClassPathScannerFactory.newDefaultScanner(classLoader);
158168

159169
if (librariesLoader == null && classesLoader == null) {
160-
this.customScanner = scanner;
170+
this.customScanner = null;
161171
return;
162172
}
163173

174+
final ClassLoader classLoader = classesLoader == null ? librariesLoader : classesLoader;
175+
final ClassPathScanner scanner = classesLoader == null ? ClassPathScannerFactory.newDefaultScanner() :
176+
ClassPathScannerFactory.newDefaultScanner(classLoader);
177+
164178
final Array<URL> urls = ArrayFactory.newArray(URL.class);
165179

166180
if (librariesLoader != null) {
@@ -178,7 +192,7 @@ public synchronized void reload() {
178192

179193
scanner.addAdditionalPaths(paths);
180194
scanner.setUseSystemClasspath(false);
181-
scanner.scan(path -> true);
195+
scanner.scan();
182196

183197
this.customScanner = scanner;
184198
}
@@ -202,13 +216,13 @@ private void updateLibraries() {
202216
if (path == null) return;
203217

204218
final Array<Path> jars = FileUtils.getFiles(path, false, JAR_EXTENSIONS);
205-
final URL[] urls = jars.stream().map(FileUtils::toUrl)
219+
final URL[] urls = jars.stream()
220+
.map(FileUtils::toUrl)
206221
.toArray(URL[]::new);
207222

208223
final URLClassLoader classLoader = new URLClassLoader(urls, getClass().getClassLoader());
209224

210225
assetManager.addClassLoader(classLoader);
211-
212226
setLibrariesLoader(classLoader);
213227
}
214228

@@ -224,7 +238,7 @@ private void updateClasses() {
224238

225239
if (currentClassLoader != null) {
226240
assetManager.removeClassLoader(currentClassLoader);
227-
setLibrariesLoader(null);
241+
setClassesLoader(null);
228242
}
229243

230244
final Path path = EDITOR_CONFIG.getClassesPath();
@@ -241,18 +255,117 @@ private void updateClasses() {
241255
});
242256
});
243257

244-
final URL[] urls = folders.stream().map(FileUtils::toUrl)
258+
final URL[] urls = folders.stream()
259+
.map(FileUtils::toUrl)
245260
.toArray(URL[]::new);
246261

247262
final ClassLoader librariesLoader = getLibrariesLoader();
248263
final ClassLoader parent = librariesLoader == null? getClass().getClassLoader() : librariesLoader;
249264
final URLClassLoader classLoader = new URLClassLoader(urls, parent);
250265

251266
assetManager.addClassLoader(classLoader);
252-
253267
setClassesLoader(classLoader);
254268
}
255269

270+
/**
271+
* Load local libraries.
272+
*/
273+
@FromAnyThread
274+
public synchronized void loadLocalLibraries(@NotNull final Array<Path> libraries) {
275+
276+
final Editor editor = Editor.getInstance();
277+
final AssetManager assetManager = editor.getAssetManager();
278+
final URLClassLoader currentClassLoader = getLocalLibrariesLoader();
279+
280+
if (currentClassLoader != null) {
281+
assetManager.removeClassLoader(currentClassLoader);
282+
setLocalLibrariesLoader(null);
283+
}
284+
285+
if (libraries.isEmpty()) {
286+
this.localLibrariesScanner = null;
287+
return;
288+
}
289+
290+
final URL[] urlArray = libraries.stream()
291+
.map(FileUtils::toUrl)
292+
.toArray(URL[]::new);
293+
294+
final URLClassLoader classLoader = new URLClassLoader(urlArray, getClass().getClassLoader());
295+
296+
assetManager.addClassLoader(classLoader);
297+
setLocalLibrariesLoader(classLoader);
298+
299+
final ClassPathScanner scanner = ClassPathScannerFactory.newDefaultScanner(classLoader);
300+
final Array<URL> urls = ArrayFactory.asArray(classLoader.getURLs());
301+
final String[] paths = urls.stream().map(url -> Utils.get(url, URL::toURI))
302+
.map(Paths::get)
303+
.map(Path::toString)
304+
.toArray(String[]::new);
305+
306+
scanner.addAdditionalPaths(paths);
307+
scanner.setUseSystemClasspath(false);
308+
scanner.scan();
309+
310+
this.localLibrariesScanner = scanner;
311+
}
312+
313+
/**
314+
* Load local classes.
315+
*/
316+
@FromAnyThread
317+
public synchronized void loadLocalClasses(@Nullable final Path output) {
318+
319+
final Editor editor = Editor.getInstance();
320+
final AssetManager assetManager = editor.getAssetManager();
321+
final URLClassLoader currentClassLoader = getLocalClassesLoader();
322+
323+
if (currentClassLoader != null) {
324+
assetManager.removeClassLoader(currentClassLoader);
325+
setLocalClassesLoader(null);
326+
}
327+
328+
if (output == null || !Files.exists(output)) {
329+
this.localClassesScanner = null;
330+
return;
331+
}
332+
333+
final Array<Path> folders = ArrayFactory.newArray(Path.class);
334+
335+
Utils.run(output, folders, (dir, toStore) -> {
336+
final DirectoryStream<Path> stream = Files.newDirectoryStream(dir);
337+
stream.forEach(subFile -> {
338+
if (Files.isDirectory(subFile)) {
339+
toStore.add(subFile);
340+
}
341+
});
342+
});
343+
344+
final URL[] urlArray = folders.stream()
345+
.map(FileUtils::toUrl)
346+
.toArray(URL[]::new);
347+
348+
final ClassLoader librariesLoader = getLocalLibrariesLoader();
349+
final ClassLoader parent = librariesLoader == null? getClass().getClassLoader() : librariesLoader;
350+
final URLClassLoader classLoader = new URLClassLoader(urlArray, parent);
351+
352+
assetManager.addClassLoader(classLoader);
353+
setLocalClassesLoader(classLoader);
354+
355+
final ClassPathScanner scanner = ClassPathScannerFactory.newDefaultScanner(classLoader);
356+
final Array<URL> urls = ArrayFactory.asArray(classLoader.getURLs());
357+
final String[] paths = urls.stream().map(url -> Utils.get(url, URL::toURI))
358+
.map(Paths::get)
359+
.map(Path::toString)
360+
.toArray(String[]::new);
361+
362+
scanner.addAdditionalPaths(paths);
363+
scanner.setUseSystemClasspath(false);
364+
scanner.scan();
365+
366+
this.localClassesScanner = scanner;
367+
}
368+
256369
/**
257370
* @param librariesLoader the additional class loader.
258371
*/
@@ -345,6 +458,24 @@ private void setLocalClassesLoader(@Nullable final URLClassLoader localClassesLo
345458
return customScanner;
346459
}
347460

461+
/**
462+
* Get the local libraries scanner.
463+
*
464+
* @return the local libraries scanner.
465+
*/
466+
private @Nullable ClassPathScanner getLocalLibrariesScanner() {
467+
return localLibrariesScanner;
468+
}
469+
470+
/**
471+
* Get the local classes scanner.
472+
*
473+
* @return the local classes scanner.
474+
*/
475+
private @Nullable ClassPathScanner getLocalClassesScanner() {
476+
return localClassesScanner;
477+
}
478+
348479
/**
349480
* Find all implementations of the interface class.
350481
*
@@ -367,6 +498,16 @@ private void setLocalClassesLoader(@Nullable final URLClassLoader localClassesLo
367498
customScanner.findImplements(result, interfaceClass);
368499
}
369500

501+
final ClassPathScanner localLibrariesScanner = getLocalLibrariesScanner();
502+
if (localLibrariesScanner != null && scope.contains(Scope.LOCAL_LIBRARIES)) {
503+
localLibrariesScanner.findImplements(result, interfaceClass);
504+
}
505+
506+
final ClassPathScanner localClassesScanner = getLocalClassesScanner();
507+
if (localClassesScanner != null && scope.contains(Scope.LOCAL_CLASSES)) {
508+
localClassesScanner.findImplements(result, interfaceClass);
509+
}
510+
370511
if (scope.contains(Scope.PLUGINS)) {
371512
final PluginManager pluginManager = PluginManager.getInstance();
372513
pluginManager.handlePlugins(plugin -> {

src/main/java/com/ss/editor/manager/RemoteControlManager.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package com.ss.editor.manager;
22

3+
import com.ss.editor.annotation.FromAnyThread;
34
import com.ss.editor.config.Config;
4-
import com.ss.rlib.logging.Logger;
5-
import com.ss.rlib.logging.LoggerManager;
65
import com.ss.rlib.network.NetworkFactory;
76
import com.ss.rlib.network.packet.ReadablePacket;
87
import com.ss.rlib.network.packet.ReadablePacketRegistry;
@@ -20,9 +19,6 @@
2019
*/
2120
public class RemoteControlManager {
2221

23-
@NotNull
24-
private static final Logger LOGGER = LoggerManager.getLogger(RemoteControlManager.class);
25-
2622
@Nullable
2723
private static RemoteControlManager instance;
2824

@@ -31,19 +27,35 @@ public class RemoteControlManager {
3127
return instance;
3228
}
3329

30+
@NotNull
31+
private final ReadablePacketRegistry packetRegistry;
32+
3433
@Nullable
35-
private ServerNetwork serverNetwork;
34+
private volatile ServerNetwork serverNetwork;
3635

3736
private RemoteControlManager() {
38-
if(Config.REMOTE_CONTROL_PORT == -1) {
39-
return;
40-
}
4137

4238
final ClasspathManager classpathManager = ClasspathManager.getInstance();
4339
final Class<ReadablePacket>[] packets = classpathManager.findImplements(ReadablePacket.class, ClasspathManager.Scope.ONLY_CORE)
4440
.toArray(Class.class);
4541

46-
serverNetwork = NetworkFactory.newDefaultAsyncServerNetwork(ReadablePacketRegistry.of(packets));
42+
this.packetRegistry = ReadablePacketRegistry.of(packets);
43+
44+
final InitializationManager initializationManager = InitializationManager.getInstance();
45+
initializationManager.addOnAfterCreateJMEContext(this::start);
46+
}
47+
48+
/**
49+
* Start the remote control if need.
50+
*/
51+
@FromAnyThread
52+
private synchronized void start() {
53+
54+
if (Config.REMOTE_CONTROL_PORT == -1) {
55+
return;
56+
}
57+
58+
serverNetwork = NetworkFactory.newDefaultAsyncServerNetwork(packetRegistry);
4759
try {
4860
serverNetwork.bind(new InetSocketAddress(Config.REMOTE_CONTROL_PORT));
4961
} catch (final IOException e) {

src/main/java/com/ss/editor/remote/control/client/ClientCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import java.nio.ByteBuffer;
99

1010
/**
11-
* The base implementation of a client packet.
11+
* The base implementation of a command.
1212
*
1313
* @author JavaSaBr
1414
*/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.ss.editor.remote.control.client;
2+
3+
import com.ss.editor.annotation.BackgroundThread;
4+
import com.ss.editor.manager.ClasspathManager;
5+
import com.ss.rlib.network.ConnectionOwner;
6+
import com.ss.rlib.network.annotation.PacketDescription;
7+
import com.ss.rlib.util.StringUtils;
8+
import com.ss.rlib.util.array.Array;
9+
import com.ss.rlib.util.array.ArrayFactory;
10+
import org.jetbrains.annotations.NotNull;
11+
12+
import java.nio.ByteBuffer;
13+
import java.nio.file.Path;
14+
import java.nio.file.Paths;
15+
16+
/**
17+
* The command to init local classpath in jMB.
18+
*
19+
* @author JavaSaBr
20+
*/
21+
@PacketDescription(id = 4)
22+
public class InitLocalClasspathClientCommand extends ClientCommand {
23+
24+
@Override
25+
@BackgroundThread
26+
protected void readImpl(@NotNull final ConnectionOwner owner, @NotNull final ByteBuffer buffer) {
27+
28+
final Array<Path> libraries = ArrayFactory.newArray(Path.class);
29+
30+
for (int i = 0, length = readInt(buffer); i < length; i++) {
31+
libraries.add(Paths.get(readString(buffer)));
32+
}
33+
34+
final String outputPath = readString(buffer);
35+
final Path output = StringUtils.isEmpty(outputPath) ? null : Paths.get(outputPath);
36+
37+
final ClasspathManager classpathManager = ClasspathManager.getInstance();
38+
classpathManager.loadLocalLibraries(libraries);
39+
classpathManager.loadLocalClasses(output);
40+
}
41+
}

0 commit comments

Comments
 (0)