This is an automated email from the ASF dual-hosted git repository.

sdedic pushed a commit to branch sdedic/feature/project-dependency-add_base2
in repository https://gitbox.apache.org/repos/asf/netbeans.git

commit d6864666dd5bda44039388f07c0d1bf0ba191b1a
Author: Svata Dedic <[email protected]>
AuthorDate: Wed Dec 13 22:43:40 2023 +0100

    Prototype of dependencies.find command
---
 .../modules/nbcode/integration/ExtraGsonSetup.java |  49 ++++-
 .../commands/DependencyFindRequest.java            |  87 +++++++++
 .../integration/commands/DependencyFindResult.java |  67 +++++++
 .../commands/ProjectDependenciesCommand.java       | 200 +++++++++++++++++++++
 4 files changed, 402 insertions(+), 1 deletion(-)

diff --git 
a/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/ExtraGsonSetup.java
 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/ExtraGsonSetup.java
index d63d16d59a..56ebb6e78a 100644
--- 
a/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/ExtraGsonSetup.java
+++ 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/ExtraGsonSetup.java
@@ -21,11 +21,21 @@ package org.netbeans.modules.nbcode.integration;
 import com.google.gson.ExclusionStrategy;
 import com.google.gson.FieldAttributes;
 import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 import org.netbeans.modules.java.lsp.server.LspGsonSetup;
 import org.netbeans.modules.project.dependency.ArtifactSpec;
+import org.netbeans.modules.project.dependency.Dependency;
+import org.netbeans.modules.project.dependency.Scope;
 import org.openide.util.lookup.ServiceProvider;
 
 /**
@@ -40,6 +50,11 @@ public class ExtraGsonSetup implements LspGsonSetup{
             "data" // NOI18N
     ));
 
+    private static final Set<String> DEPENDENCY_BLOCK_FIELDS = new 
HashSet<>(Arrays.asList(
+            "parent", // NOI18N
+            "data" // NOI18N
+    ));
+
     @Override
     public void configureBuilder(GsonBuilder b) {
         b.addSerializationExclusionStrategy(new ExclusionStrategy() {
@@ -50,7 +65,9 @@ public class ExtraGsonSetup implements LspGsonSetup{
                 if (fa.getDeclaringClass() == ArtifactSpec.class) {
                     return ARTIFACT_BLOCK_FIELDS.contains(fa.getName());
                 } else if 
(Throwable.class.isAssignableFrom(fa.getDeclaredClass())) {
-
+                    return DEPENDENCY_BLOCK_FIELDS.contains(fa.getName());
+                } else if (fa.getDeclaringClass() == Dependency.class) {
+                    
                 }
                 return false;
             }
@@ -60,6 +77,36 @@ public class ExtraGsonSetup implements LspGsonSetup{
                 return false;
             }
         });
+        b.registerTypeAdapter(ArtifactSpec.class, new ArtifactDeserializer());
+        b.registerTypeAdapter(Scope.class, new ScopeSerializer());
     }
     
+    class ScopeSerializer implements JsonSerializer<Scope> {
+
+        @Override
+        public JsonElement serialize(Scope t, Type type, 
JsonSerializationContext jsc) {
+            return jsc.serialize(t.name());
+        }
+    }
+    
+    
+    class ArtifactDeserializer implements JsonDeserializer<ArtifactSpec> {
+
+        @Override
+        public ArtifactSpec deserialize(JsonElement je, Type type, 
JsonDeserializationContext jdc) throws JsonParseException {
+            JsonObject obj = je.getAsJsonObject();
+            String g = obj.has("groupId") ? 
obj.getAsJsonPrimitive("groupId").getAsString() : null;
+            String a = obj.has("artifactId") ? 
obj.getAsJsonPrimitive("artifactId").getAsString() : null;
+            String v = obj.has("versionSpec") ? 
obj.getAsJsonPrimitive("versionSpec").getAsString() : null;
+            String c = obj.has("classifier") ? 
obj.getAsJsonPrimitive("classifier").getAsString() : null;
+            String t = obj.has("type") ? 
obj.getAsJsonPrimitive("type").getAsString() : null;
+            
+            
+            ArtifactSpec.Builder b = ArtifactSpec.builder(g, a, v, 
null).classifier(c).type(t);
+            if (v != null && v.contains("-SNAPSHOT")) {
+                b.versionKind(ArtifactSpec.VersionKind.SNAPSHOT);
+            }
+            return b.build();
+        }
+    }
 }
diff --git 
a/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/DependencyFindRequest.java
 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/DependencyFindRequest.java
new file mode 100644
index 0000000000..5f15529bf9
--- /dev/null
+++ 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/DependencyFindRequest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.nbcode.integration.commands;
+
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.netbeans.modules.project.dependency.ArtifactSpec;
+
+/**
+ *
+ * @author sdedic
+ */
+public class DependencyFindRequest {
+    /**
+     * URI of the project.
+     */
+    @NonNull
+    private String uri;
+    
+    /**
+     * Scope(s) to search.
+     */
+    private List<String> scopes;
+    
+    /**
+     * Artifacts to search for.
+     */
+    private List<ArtifactSpec>  artifacts;
+
+    /**
+     * Return contents of the dependency
+     */
+    private boolean returnContents;
+
+    @Pure
+    @NonNull
+    public String getUri() {
+        return uri;
+    }
+
+    @Pure
+    public List<String> getScopes() {
+        return scopes;
+    }
+
+    @Pure
+    public List<ArtifactSpec> getArtifacts() {
+        return artifacts;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    public void setScopes(List<String> scopes) {
+        this.scopes = scopes;
+    }
+
+    public void setArtifacts(List<ArtifactSpec> artifacts) {
+        this.artifacts = artifacts;
+    }
+
+    public boolean isReturnContents() {
+        return returnContents;
+    }
+
+    public void setReturnContents(boolean returnContents) {
+        this.returnContents = returnContents;
+    }
+}
diff --git 
a/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/DependencyFindResult.java
 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/DependencyFindResult.java
new file mode 100644
index 0000000000..3b6f7fded7
--- /dev/null
+++ 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/DependencyFindResult.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.nbcode.integration.commands;
+
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.netbeans.modules.project.dependency.ArtifactSpec;
+import org.netbeans.modules.project.dependency.Dependency;
+
+/**
+ *
+ * @author sdedic
+ */
+public class DependencyFindResult {
+    @NonNull
+    private String uri;
+    private ArtifactSpec project;
+    private List<Dependency> matches = Collections.emptyList();
+
+    @Pure
+    public ArtifactSpec getProject() {
+        return project;
+    }
+
+    public void setProject(ArtifactSpec project) {
+        this.project = project;
+    }
+
+    @Pure
+    @NonNull
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    @Pure
+    @NonNull
+    public List<Dependency> getMatches() {
+        return matches;
+    }
+
+    @Pure
+    public void setMatches(List<Dependency> matches) {
+        this.matches = matches == null ? Collections.emptyList() : matches;
+    }
+}
diff --git 
a/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/ProjectDependenciesCommand.java
 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/ProjectDependenciesCommand.java
new file mode 100644
index 0000000000..6a6594f096
--- /dev/null
+++ 
b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/commands/ProjectDependenciesCommand.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.nbcode.integration.commands;
+
+import com.google.gson.Gson;
+import java.net.MalformedURLException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import org.netbeans.api.project.FileOwnerQuery;
+import org.netbeans.api.project.Project;
+import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.project.dependency.ArtifactSpec;
+import org.netbeans.modules.project.dependency.Dependency;
+import org.netbeans.modules.project.dependency.DependencyResult;
+import org.netbeans.modules.project.dependency.ProjectDependencies;
+import org.netbeans.modules.project.dependency.ProjectOperationException;
+import org.netbeans.modules.project.dependency.Scope;
+import org.netbeans.spi.lsp.CommandProvider;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.URLMapper;
+import org.openide.util.Lookup;
+import org.openide.util.RequestProcessor;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author sdedic
+ */
+@ServiceProvider(service = CommandProvider.class)
+public class ProjectDependenciesCommand implements CommandProvider {
+    
+    private static final RequestProcessor RP = new 
RequestProcessor(ProjectDependenciesCommand.class.getName(), 5);
+                                                            
+    private static final String COMMAND_GET_DEPENDENCIES = 
"nbls.project.dependencies.find";
+    private static final String COMMAND_CHANGE_DEPENDENCIES = 
"nbls.project.dependencies.change";
+    
+    private static final Set COMMANDS = new HashSet<>(Arrays.asList(
+            COMMAND_GET_DEPENDENCIES,
+            COMMAND_CHANGE_DEPENDENCIES
+    ));
+
+    @Override
+    public Set<String> getCommands() {
+        return COMMANDS;
+    }
+
+    private final Gson gson = new Gson();
+    
+    static class K {
+        final Dependency d;
+
+        public K(Dependency d) {
+            this.d = d;
+        }
+        
+        public int hashCode() {
+            return d.getArtifact().hashCode() << 7 + 
d.getScope().name().hashCode();
+        }
+        
+        public boolean equals(Object o) {
+            if (!(o instanceof K)) {
+                return false;
+            }
+            K other = (K)o;
+            return other.d.getArtifact().equals(d.getArtifact()) && 
other.d.getScope().equals(d.getScope());
+        }
+    }
+    
+    private Gson gson() {
+        Gson inst = Lookup.getDefault().lookup(Gson.class);
+        return inst != null ? inst : gson;
+    }
+
+    @Override
+    public CompletableFuture<Object> runCommand(String command, List<Object> 
arguments) {
+        switch (command) {
+            case COMMAND_GET_DEPENDENCIES: {
+                DependencyFindRequest request = 
gson().fromJson(gson().toJson(arguments.get(0)), DependencyFindRequest.class);
+                FileObject dir;
+                try {
+                    dir = Utils.fromUri(request.getUri());
+                } catch (MalformedURLException ex) {
+                    CompletableFuture res = new CompletableFuture();
+                    res.completeExceptionally(ex);
+                    return res;
+                }
+                if (dir == null) {
+                    throw new IllegalArgumentException("Not a file");
+                }
+                
+                Project p = FileOwnerQuery.getOwner(dir);
+                if (p == null) {
+                    return CompletableFuture.completedFuture(null);
+                }
+                List<ArtifactSpec> matches = request.getArtifacts();
+                // PENDING: make 'online' a parameter
+                Scope[] scopes = request.getScopes() == null ? 
+                        null : request.getScopes().stream().map(sn -> 
Scope.named(sn)).toArray(s -> new Scope[s]);
+                ProjectDependencies.DependencyQueryBuilder b = 
ProjectDependencies.newBuilder().
+                        online().
+                        scope(scopes);
+                CompletableFuture future = new CompletableFuture();
+                // do not block the main thread
+                RP.post(() -> {
+                    DependencyResult r;
+                    
+                    try {
+                        r = ProjectDependencies.findDependencies(p, b.build());
+                    } catch (ProjectOperationException ex) {
+                        future.completeExceptionally(ex);
+                        return;
+                    } catch (ThreadDeath td) {
+                        throw td;
+                    } catch (Throwable t) {
+                        future.completeExceptionally(t);
+                        return;
+                    }
+                    DependencyFindResult res = new DependencyFindResult();
+                    res.setUri(URLMapper.findURL(p.getProjectDirectory(), 
URLMapper.EXTERNAL).toString());
+                    res.setProject(r.getRoot().getArtifact());
+                    
+                    Queue<Dependency> toProcess = new ArrayDeque<>();
+                    List<Dependency> accepted = new ArrayList<>();
+                    toProcess.addAll(r.getRoot().getChildren());
+                    
+                    Set<K> seen = new HashSet<>();
+                    NEXT: while (!toProcess.isEmpty()) {
+                        Dependency d = toProcess.poll();
+                        ArtifactSpec a = d.getArtifact();
+                        if (a == null) {
+                            // PENDING: not supported atm
+                            continue;
+                        }
+                        if (!seen.add(new K(d))) {
+                            continue;
+                        }
+                        toProcess.addAll(d.getChildren());
+                        if (matches != null && !matches.isEmpty()) {
+                            for (ArtifactSpec test : matches) {
+                                if (test.getGroupId() != null && 
!test.getGroupId().equals(a.getGroupId())) {
+                                    continue NEXT;
+                                }
+                                if (test.getArtifactId() != null && 
!test.getArtifactId().equals(a.getArtifactId())) {
+                                    continue NEXT;
+                                }
+                                if (test.getVersionSpec() != null && 
!test.getVersionSpec().equals(a.getVersionSpec())) {
+                                    continue NEXT;
+                                }
+                                if (test.getClassifier() != null && 
!test.getClassifier().equals(a.getClassifier())) {
+                                    continue NEXT;
+                                }
+                                if (test.getType()!= null && 
!test.getType().equals(a.getType())) {
+                                    continue NEXT;
+                                }
+                                // match found, OK
+                                break;
+                            }
+                        }
+                        
+                        if (request.isReturnContents()) {
+                            accepted.add(d);
+                        } else {
+                            accepted.add(Dependency.create(a, d.getScope(), 
Collections.emptyList(), null));
+                        }
+                    }
+                    res.setMatches(accepted);
+                    future.complete(res);
+                });
+                return future;
+            }
+
+            case COMMAND_CHANGE_DEPENDENCIES:
+        }
+        return null;
+    }
+    
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to