sdedic commented on code in PR #7413:
URL: https://github.com/apache/netbeans/pull/7413#discussion_r1628379447


##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/Steps.java:
##########
@@ -0,0 +1,676 @@
+/*
+ * 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.cloud.oracle.assets;
+
+import com.oracle.bmc.identity.Identity;
+import com.oracle.bmc.identity.IdentityClient;
+import com.oracle.bmc.identity.model.Compartment;
+import com.oracle.bmc.identity.model.Tenancy;
+import com.oracle.bmc.identity.requests.ListCompartmentsRequest;
+import com.oracle.bmc.identity.responses.ListCompartmentsResponse;
+import com.oracle.bmc.model.BmcException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Optional;
+import java.util.TreeMap;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectInformation;
+import org.netbeans.api.project.ProjectUtils;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import org.netbeans.modules.cloud.oracle.OCIProfile;
+import org.netbeans.modules.cloud.oracle.OCISessionInitiator;
+import org.netbeans.modules.cloud.oracle.bucket.BucketNode;
+import org.netbeans.modules.cloud.oracle.compartment.CompartmentItem;
+import org.netbeans.modules.cloud.oracle.compute.ClusterNode;
+import org.netbeans.modules.cloud.oracle.compute.ComputeInstanceNode;
+import org.netbeans.modules.cloud.oracle.database.DatabaseItem;
+import org.netbeans.modules.cloud.oracle.database.DatabaseNode;
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+import org.netbeans.modules.cloud.oracle.items.TenancyItem;
+import org.netbeans.modules.cloud.oracle.vault.VaultNode;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+import org.openide.util.Pair;
+import org.openide.util.RequestProcessor;
+
+/**
+ *
+ * @author Jan Horvath
+ */
[email protected]({
+    "Databases=Oracle Autonomous Database",
+    "Vault=OCI Vault",
+    "Bucket=Object Storage Bucket",
+    "Cluster=Oracle Container Engine",
+    "Compute=Compute Instance"
+})
+public final class Steps {
+    private static final Logger LOG = Logger.getLogger(Steps.class.getName());
+    private static final RequestProcessor RP = new RequestProcessor("Steps"); 
//NOI18N
+    private static Steps instance = null;
+
+    public static synchronized Steps getDefault() {
+        if (instance == null) {
+            instance = new Steps();
+        }
+        return instance;
+    }
+
+    public CompletableFuture<Object> executeMultistep(Step firstStep, Lookup 
lookup) {
+        DialogDisplayer dd = DialogDisplayer.getDefault();
+        CompletableFuture future = new CompletableFuture();
+        RP.post(() -> {
+            Multistep multistep = new Multistep(firstStep, lookup);
+            NotifyDescriptor.ComposedInput ci = new 
NotifyDescriptor.ComposedInput(Bundle.AddSuggestedItem(), 3, 
multistep.createInput());
+            if (DialogDescriptor.OK_OPTION == dd.notify(ci)) {
+                future.complete(multistep.getResult());
+            } else {
+                future.complete(null);
+            }
+        });
+        return future;
+    }
+
+    private static class Multistep {
+
+        private final LinkedList<Step> steps = new LinkedList<>();
+        private final Lookup lookup;
+
+        Multistep(Step firstStep, Lookup lookup) {
+            steps.add(firstStep);
+            this.lookup = lookup;
+        }
+
+        NotifyDescriptor.ComposedInput.Callback createInput() {
+            return new NotifyDescriptor.ComposedInput.Callback() {
+                private int lastNumber = 0;
+
+                private void readValue(Step step, NotifyDescriptor desc) {
+                    String selected = null;
+                    if (!step.onlyOneChoice()) {
+                        if (desc instanceof NotifyDescriptor.QuickPick) {
+                            for (NotifyDescriptor.QuickPick.Item item : 
((NotifyDescriptor.QuickPick) desc).getItems()) {
+                                if (item.isSelected()) {
+                                    selected = item.getLabel();
+                                    break;
+                                }
+                            }
+                        } else if (desc instanceof NotifyDescriptor.InputLine) 
{
+                            selected = ((NotifyDescriptor.InputLine) 
desc).getInputText();
+                        }
+                        step.setValue(selected);
+                    }
+                }
+
+                @Override
+                public NotifyDescriptor 
createInput(NotifyDescriptor.ComposedInput input, int number) {
+                    if (number == 1) {
+                        while (steps.size() > 1) {
+                            steps.removeLast();
+                        }
+                        steps.getLast().prepare(null, lookup);
+                    } else if (lastNumber > number) {
+                        steps.removeLast();
+                        while (steps.getLast().onlyOneChoice() && steps.size() 
> 1) {
+                            steps.removeLast();
+                        }
+                        lastNumber = number;
+                        return steps.getLast().createInput();
+                    } else {
+                        readValue(steps.getLast(), input.getInputs()[number - 
2]);
+                        steps.add(steps.getLast().getNext());
+                    }
+                    lastNumber = number;
+
+                    while (steps.getLast() != null && 
steps.getLast().onlyOneChoice()) {
+                        steps.add(steps.getLast().getNext());
+                    }
+                    if (steps.getLast() == null) {
+                        steps.removeLast();
+                        return null;
+                    }
+                    return steps.getLast().createInput();
+                }
+            };
+        }
+
+        public Object getResult() {
+            return steps.getLast().getValue();
+        }
+    }
+
+    static final class TenancyStep implements Step<Object, TenancyItem> {
+
+        List<OCIProfile> profiles = new LinkedList<>();
+        private AtomicReference<TenancyItem> selected = new 
AtomicReference<>();
+        private Lookup lookup;
+
+        @Override
+        public NotifyDescriptor createInput() {
+            if (onlyOneChoice()) {
+                throw new IllegalStateException("No data to create input"); // 
NOI18N
+            }
+            String title = Bundle.SelectProfile();
+            List<NotifyDescriptor.QuickPick.Item> items = new 
ArrayList<>(profiles.size());
+            for (OCIProfile p : profiles) {
+                Tenancy t = p.getTenancyData();
+                if (t != null) {
+                    items.add(new NotifyDescriptor.QuickPick.Item(p.getId(), 
Bundle.SelectProfile_Description(t.getName(), t.getHomeRegionKey())));
+                }
+            }
+            if (profiles.stream().filter(p -> 
p.getTenancy().isPresent()).count() == 0) {
+                title = Bundle.NoProfile();
+            }
+            return new NotifyDescriptor.QuickPick(title, title, items, false);
+        }
+
+        @Override
+        public Step getNext() {
+            return new CompartmentStep().prepare(getValue(), lookup);
+        }
+
+        @Override
+        public Step<Object, TenancyItem> prepare(Object i, Lookup lookup) {
+            this.lookup = lookup;
+            ProgressHandle h = 
ProgressHandle.createHandle(Bundle.CollectingProfiles());
+            h.start();
+            h.progress(Bundle.CollectingProfiles_Text());
+            try {
+                profiles = OCIManager.getDefault().getConnectedProfiles();
+            } finally {
+                h.finish();
+            }
+            return this;
+        }
+
+        public void setValue(String value) {
+            for (OCIProfile profile : profiles) {
+                if (profile.getId().equals(value)) {
+                    profile.getTenancy().ifPresent(t -> this.selected.set(t));
+                    break;
+                }
+            }
+        }
+
+        @Override
+        public TenancyItem getValue() {
+            if (onlyOneChoice()) {
+                return profiles.stream()
+                        .map(p -> p.getTenancy())
+                        .filter(Optional::isPresent)
+                        .map(Optional::get)
+                        .findFirst()
+                        .get();
+            }
+            return selected.get();
+        }
+
+        @Override
+        public boolean onlyOneChoice() {
+            return profiles.stream().filter(p -> 
p.getTenancy().isPresent()).count() == 1;
+        }
+    }
+
+    static final class CompartmentStep implements Step<TenancyItem, 
CompartmentItem> {
+
+        private Map<String, OCIItem> compartments = null;
+        private CompartmentItem selected;
+        private Lookup lookup;
+
+        public Step<TenancyItem, CompartmentItem> prepare(TenancyItem tenancy, 
Lookup lookup) {
+            this.lookup = lookup;
+            ProgressHandle h = 
ProgressHandle.createHandle(Bundle.CollectingItems());
+            h.start();
+            h.progress(Bundle.CollectingItems_Text());
+            try {
+                compartments = getFlatCompartment(tenancy);
+            } finally {
+                h.finish();
+            }
+            return this;
+        }
+
+        @Override
+        public NotifyDescriptor createInput() {
+            if (onlyOneChoice()) {
+                throw new IllegalStateException("Input shouldn't be displayed 
for one choice"); // NOI18N
+            }
+            if (compartments.isEmpty()) {
+                return createQuickPick(compartments, Bundle.NoCompartment());
+            }
+            return createQuickPick(compartments, Bundle.SelectCompartment());
+        }
+
+        @Override
+        public Step getNext() {
+            return new SuggestedStep().prepare(getValue(), lookup);
+        }
+
+        @Override
+        public void setValue(String selected) {
+            this.selected = (CompartmentItem) compartments.get(selected);
+        }
+
+        @Override
+        public CompartmentItem getValue() {
+            if (onlyOneChoice()) {
+                return (CompartmentItem) 
compartments.values().iterator().next();
+            }
+            return selected;
+        }
+
+        @Override
+        public boolean onlyOneChoice() {
+            return compartments.size() == 1;
+        }
+    }
+
+    /**
+     * Context of SuggestedStep. Determines next step.
+     */
+    public interface SuggestedContext {
+
+        String getItemType();
+
+        Step getNextStep();
+
+        public void setItemType(String selected);
+    }
+
+    /**
+     * Show list of items for a suggested type.
+     * 
+     */
+    static class SuggestedStep implements Step<CompartmentItem, OCIItem> {
+
+        private Map<String, OCIItem> items = new HashMap<>();
+        private OCIItem selected;
+        private Lookup lookup;
+        private SuggestedContext context = null;
+
+        public SuggestedStep prepare(CompartmentItem compartment, Lookup 
lookup) {
+            this.lookup = lookup;
+            context = lookup.lookup(SuggestedContext.class);
+            ProgressHandle h = 
ProgressHandle.createHandle(Bundle.CollectingItems());
+            h.start();
+            h.progress(Bundle.CollectingItems_Text());
+            try {
+                getItemsByPath(compartment, 
context.getItemType()).forEach((db) -> items.put(db.getName(), db));
+            } finally {
+                h.finish();
+            }
+            return this;
+        }
+
+        private String getSuggestedItemName() {
+            switch (context.getItemType()) {
+                case "Databases":
+                    return Bundle.Databases();
+                case "Vault":
+                    return Bundle.Vault();
+                case "Bucket":
+                    return Bundle.Bucket();
+                case "Cluster":
+                    return Bundle.Cluster();
+                case "ComputeInstance":
+                    return Bundle.Compute();
+            }
+            throw new MissingResourceException("Missing OCI type", null, 
context.getItemType());
+        }
+
+        @Override
+        public NotifyDescriptor createInput() {
+            return createQuickPick(items, 
Bundle.SelectItem(getSuggestedItemName()));
+        }
+
+        @Override
+        public Step getNext() {
+            Step next = context.getNextStep();
+            if (next != null) {
+                next.prepare(getValue(), lookup);
+            }
+            return next;
+        }
+
+        @Override
+        public void setValue(String selected) {
+            this.selected = items.get(selected);
+        }
+
+        @Override
+        public OCIItem getValue() {
+            if (onlyOneChoice()) {
+                selected = items.values().iterator().next();
+            }
+            return selected;
+        }
+
+        @Override
+        public boolean onlyOneChoice() {
+            return false;
+        }
+    }
+
+    private static <T extends OCIItem> NotifyDescriptor.QuickPick 
createQuickPick(Map<String, T> ociItems, String title) {
+        List<NotifyDescriptor.QuickPick.Item> items = new ArrayList<> ();
+        for (Map.Entry<String, T> entry : ociItems.entrySet()) {
+            String description = entry.getValue().getDescription();
+            if (description == null || description.isBlank()) {
+                description = title;

Review Comment:
   Just verifying: in case that all items, which have ociItem.getDescription() 
== null will get the same description (title) - not their ociItem.getName() ?



-- 
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]


---------------------------------------------------------------------
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