Croway commented on code in PR #23129:
URL: https://github.com/apache/camel/pull/23129#discussion_r3225041054


##########
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java:
##########
@@ -179,30 +221,247 @@ public static Map<String, Plugin> 
getActivePlugins(CamelJBangMain main, String r
                     versionCheck(main, version, firstVersion, command);
                 }
 
-                Optional<Plugin> plugin = getPlugin(command, version, gav, 
repos, main.getOut());
-                if (plugin.isPresent()) {
-                    activePlugins.put(command, plugin.get());
+                ResolveResult res = resolvePlugin(properties, command, 
version, gav, repos, main.getOut());
+                if (res.plugin().isPresent()) {
+                    activePlugins.put(command, res.plugin().get());
+                    if (res.cacheWritten()) {
+                        configDirty = true;
+                    }
                 } else {
                     main.getOut().println("camel-jbang-plugin-" + command + " 
not found. Exit");
                     main.quit(1);
                 }
             }
+            if (configDirty) {
+                savePluginConfig(config);
+            }
         }
 
         return activePlugins;
     }
 
     public static Optional<Plugin> getPlugin(String name, String 
defaultVersion, String gav, String repos, Printer printer) {
+        return resolvePlugin(null, name, defaultVersion, gav, repos, 
printer).plugin();
+    }
+
+    /**
+     * Resolves a plugin by trying, in order: the cached metadata in the 
plugin entry (fast path with no IO beyond
+     * size+mtime checks), the factory finder (embedded plugin on the JVM 
classpath), and finally the Maven downloader.
+     * When the downloader runs, the resolved classpath is captured into the 
plugin entry's {@code resolved} block so
+     * subsequent invocations take the fast path.
+     */
+    private static ResolveResult resolvePlugin(
+            JsonObject entry, String name, String defaultVersion, String gav, 
String repos, Printer printer) {
+        Optional<Plugin> cached = loadFromCache(entry, defaultVersion, gav, 
repos);
+        if (cached.isPresent()) {
+            return new ResolveResult(cached, false);
+        }
+
         Optional<Plugin> plugin = 
FACTORY_FINDER.newInstance("camel-jbang-plugin-" + name, Plugin.class);
-        if (plugin.isEmpty()) {
-            final MavenGav mavenGav = dependencyAsMavenGav(gav);
-            final String group = extractGroup(mavenGav, "org.apache.camel");
-            final String depVersion = extractVersion(mavenGav, defaultVersion);
+        if (plugin.isPresent()) {
+            return new ResolveResult(plugin, false);
+        }
+
+        final MavenGav mavenGav = dependencyAsMavenGav(gav);
+        final String group = extractGroup(mavenGav, "org.apache.camel");
+        final String depVersion = extractVersion(mavenGav, defaultVersion);
+
+        DownloadResult dr = downloadPlugin(name, defaultVersion, depVersion, 
group, repos, printer);
+        boolean cacheWritten = false;
+        if (dr.plugin().isPresent() && entry != null && dr.classLoader() != 
null && dr.className() != null) {
+            cacheWritten = writeCache(entry, defaultVersion, gav, repos, 
dr.className(), dr.classLoader(), name, depVersion);
+        }
+        return new ResolveResult(dr.plugin(), cacheWritten);
+    }
+
+    private static Optional<Plugin> loadFromCache(JsonObject entry, String 
camelVersion, String gav, String repos) {
+        if (entry == null) {
+            return Optional.empty();
+        }
+        JsonObject resolved = entry.getMap("resolved");
+        if (resolved == null) {
+            return Optional.empty();
+        }
+        if (!sameCamelVersion(asString(resolved.get("camelVersion")), 
camelVersion)) {
+            return Optional.empty();
+        }
+        if (!nullSafeEquals(normalize(asString(resolved.get("gav"))), 
normalize(gav))) {
+            return Optional.empty();
+        }
+        if (!nullSafeEquals(normalize(asString(resolved.get("repos"))), 
normalize(repos))) {
+            return Optional.empty();
+        }
+        String className = asString(resolved.get("className"));
+        if (className == null || className.isBlank()) {
+            return Optional.empty();
+        }
+        Object cpObj = resolved.get("classpath");
+        if (!(cpObj instanceof Collection)) {
+            return Optional.empty();
+        }
+        Collection<?> classpath = (Collection<?>) cpObj;
+        if (classpath.isEmpty()) {
+            return Optional.empty();
+        }
+
+        List<URL> urls = new ArrayList<>(classpath.size());
+        for (Object o : classpath) {
+            if (!(o instanceof Map)) {
+                return Optional.empty();
+            }
+            Map<?, ?> jar = (Map<?, ?>) o;
+            Path p = validateFileEntry(jar);
+            if (p == null) {
+                return Optional.empty();
+            }
+            try {
+                urls.add(p.toUri().toURL());
+            } catch (IOException e) {
+                return Optional.empty();
+            }
+        }
+
+        // If the cache tracks the plugin POM, validate it too. Detects 
POM-only changes (e.g. a SNAPSHOT
+        // plugin's transitive deps changed without a jar rebuild).
+        Object pomObj = resolved.get("pom");
+        if (pomObj instanceof Map) {

Review Comment:
   Use `(pomObj instanceof Map map)` to avoid extra cast



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to