Browse Source

Merge pull request #448 from peedeeboy/bugfix/gradle_project_assetmanager_3

* Improve ProjectAssetManager's Gradle support
Rickard Edén 2 years ago
parent
commit
9625985232

+ 61 - 2
jme3-core/src/com/jme3/gde/core/assets/ProjectAssetManager.java

@@ -37,6 +37,7 @@ import com.jme3.asset.AssetManager;
 import com.jme3.asset.DesktopAssetManager;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -45,9 +46,11 @@ import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.netbeans.api.java.classpath.ClassPath;
@@ -57,6 +60,9 @@ import org.netbeans.api.project.ProjectManager;
 import org.netbeans.api.project.ProjectUtils;
 import org.netbeans.api.project.SourceGroup;
 import org.netbeans.api.project.Sources;
+import org.netbeans.modules.gradle.api.GradleBaseProject;
+import org.netbeans.modules.gradle.java.api.GradleJavaProject;
+import org.netbeans.modules.gradle.java.api.GradleJavaSourceSet;
 import org.openide.DialogDisplayer;
 import org.openide.NotifyDescriptor;
 import org.openide.filesystems.FileAttributeEvent;
@@ -179,6 +185,46 @@ public class ProjectAssetManager extends DesktopAssetManager {
                     }
                 }
             }
+            
+            // Gradle
+            FileObject rootDir = FileUtil.toFileObject(GradleBaseProject.get(project).getRootDir());
+            Set<File> runtimeFiles = new HashSet<>();
+            try {
+                Project rootPrj = ProjectManager.getDefault().findProject(rootDir);
+                GradleJavaProject rootGjp = GradleJavaProject.get(rootPrj);
+                for(GradleJavaSourceSet sourceSet : rootGjp.getSourceSets().values()) {
+                    if(sourceSet.getName().equals("main")) {
+                        runtimeFiles = sourceSet.getRuntimeClassPath();
+                    }
+                }           
+            } catch (IOException ex) { 
+                Exceptions.printStackTrace(ex);
+            } catch (IllegalArgumentException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+            
+            for(File file : runtimeFiles) {
+                // logger.info(file.getName() + " : "  + file.getAbsolutePath());
+                FileObject fo = FileUtil.toFileObject(file);
+                if(fo != null && !fo.isFolder()) {
+                    logger.info(fo.toURL().toExternalForm());
+                    if (!fo.equals(getAssetFolder())) {
+                            fo.addRecursiveListener(listener);
+                            logger.log(Level.FINE, "Add classpath:{0}", fo);
+                            classPathItems.add(new ClassPathItem(fo, listener));
+                            urls.add(fo.toURL());
+                        }
+                    if (fo.toURL().toExternalForm().startsWith("jar")) {
+                            logger.log(Level.FINE, "Add Gradle locator:{0}", fo.toURL());
+                            jarItems.add(fo);
+                            registerLocator(fo.toURL().toExternalForm(),
+                                    "com.jme3.asset.plugins.UrlLocator");
+                        }
+                }
+                
+                
+            }
+            
             loader = new URLClassLoader(urls.toArray(new URL[urls.size()]), getClass().getClassLoader());
             addClassLoader(loader);
             logger.log(Level.FINE, "Updated {0} classpath entries and {1} url locators for project {2}", new Object[]{classPathItems.size(), jarItems.size(), project.toString()});
@@ -225,7 +271,7 @@ public class ProjectAssetManager extends DesktopAssetManager {
         }
     };
 
-    private void updateClassLoader() {
+    public void updateClassLoader() {
         ProjectManager.mutex().postWriteRequest(new Runnable() {
             public void run() {
                 synchronized (classPathItems) {
@@ -478,6 +524,11 @@ public class ProjectAssetManager extends DesktopAssetManager {
             while (classPathItemsIter.hasNext()) {
                 ClassPathItem classPathItem = classPathItemsIter.next();
                 FileObject jarFile = classPathItem.object;
+                
+                // Gradle projects don't know that the dependency is a Jar file
+                if (FileUtil.isArchiveFile(jarFile)) {
+                    jarFile = FileUtil.getArchiveRoot(jarFile);
+                }
 
                 Enumeration<FileObject> jarEntry = (Enumeration<FileObject>) jarFile.getChildren(true);
                 while (jarEntry.hasMoreElements()) {
@@ -488,6 +539,7 @@ public class ProjectAssetManager extends DesktopAssetManager {
                         }
                     }
                 }
+
             }
             return list;
         }
@@ -502,7 +554,14 @@ public class ProjectAssetManager extends DesktopAssetManager {
                 ClassPathItem classPathItem = classPathItemsIter.next();
                 FileObject jarFile = classPathItem.object;
 
-                Enumeration<FileObject> jarEntry = (Enumeration<FileObject>) jarFile.getChildren(true);
+                Enumeration<FileObject> jarEntry;
+                if (FileUtil.isArchiveFile(jarFile)) {
+                    FileObject jarFileRoot = FileUtil.getArchiveRoot(jarFile);
+                    jarEntry = (Enumeration<FileObject>) jarFileRoot.getChildren(true);
+                } else {
+                    jarEntry = (Enumeration<FileObject>) jarFile.getChildren(true);
+                }
+
                 while (jarEntry.hasMoreElements()) {
                     FileObject jarEntryAsset = jarEntry.nextElement();
                     if (jarEntryAsset.getPath().equalsIgnoreCase(name)) {

+ 68 - 0
jme3-core/src/com/jme3/gde/core/assets/actions/UpdateProjectAssetManagerAfterBuild.java

@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2009-2023 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.gde.core.assets.actions;
+
+import com.jme3.gde.core.assets.ProjectAssetManager;
+import java.io.PrintWriter;
+import org.netbeans.api.project.Project;
+import org.netbeans.modules.gradle.api.NbGradleProject;
+import org.netbeans.modules.gradle.spi.actions.AfterBuildActionHook;
+import org.netbeans.spi.project.ProjectServiceProvider;
+import org.openide.util.Lookup;
+
+/**
+ * Hook that fires after a Gradle JME project has been built and requests
+ * the ProjectAssetManager to update its ClassLoader (e.g. in case new
+ * dependencies have been added)
+ * 
+ * @author peedeeboy
+ */
+@ProjectServiceProvider(service = AfterBuildActionHook.class, projectType = NbGradleProject.GRADLE_PROJECT_TYPE)
+public class UpdateProjectAssetManagerAfterBuild implements AfterBuildActionHook {
+
+    final Project project;
+
+    public UpdateProjectAssetManagerAfterBuild(Project project) {
+        this.project = project;
+    }
+    
+    @Override
+    public void afterAction(String string, Lookup lkp, int i, PrintWriter writer) {
+        ProjectAssetManager projectAssetManager = project
+                .getLookup()
+                .lookup(ProjectAssetManager.class);
+        if (projectAssetManager != null) {
+            projectAssetManager.updateClassLoader();
+        }
+    }
+    
+}