/*
 * Copyright 2017-present Open Networking Foundation
 *
 * Licensed 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.onosproject.cli;

import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.osgi.service.component.runtime.ServiceComponentRuntime;
import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;

import java.util.Formatter;

/**
 * CLI command to dump out the SCR components list in the old karaf format.
 */
@Service
@Command(scope = "onos", name = "scr-list",
         description = "List components")
public class ScrListCommand extends AbstractShellCommand {

    @Override
    protected void doExecute() {
        StringBuilder output = new StringBuilder();
        Formatter formatter = new Formatter(output);
        ServiceComponentRuntime scrService = get(ServiceComponentRuntime.class);

        scrService.getComponentDescriptionDTOs()
            .forEach(componentDto -> {
                scrService.getComponentConfigurationDTOs(componentDto)
                    .forEach(configurationDto -> {
                        String state;
                        switch (configurationDto.state) {
                            case ComponentConfigurationDTO.ACTIVE: {
                                state = "ACTIVE";
                                break;
                            }
                            case ComponentConfigurationDTO.SATISFIED: {
                                state = "SATISFIED";
                                break;
                            }
                            default: {
                                state = "UNKNOWN";
                            }
                        }
                        formatter.format("%3d | %9s | %s\n", configurationDto.id, state, componentDto.name);
                    });
                });
        print(output.toString());
    }

}

@@ -1474,32 +1474,58 @@
 mponentDto -%3E %7B%0A
+                try %7B%0A    
                 
@@ -1591,32 +1591,36 @@
                 
+  
+  
 .forEach(configu
@@ -1654,24 +1654,28 @@
             
+    
 String state
@@ -1700,16 +1700,20 @@
         
+ 
+   
 switch (
@@ -1734,24 +1734,28 @@
 to.state) %7B%0A
+    
             
@@ -1835,32 +1835,36 @@
                 
+    
 state = %22ACTIVE%22
@@ -1865,16 +1865,20 @@
 CTIVE%22;%0A
+    
         
@@ -1928,32 +1928,36 @@
                 
+    
 %7D%0A              
@@ -1962,32 +1962,36 @@
                 
+ 
+   
 case ComponentCo
@@ -2014,24 +2014,28 @@
 ATISFIED: %7B%0A
+    
             
@@ -2099,32 +2099,36 @@
                 
+    
 break;%0A         
@@ -2138,34 +2138,42 @@
                 
+   
+ 
 %7D%0A
+    
                 
@@ -2191,24 +2191,28 @@
  default: %7B%0A
+    
             
@@ -2270,32 +2270,36 @@
                 
+    
 %7D%0A              
@@ -2300,34 +2300,42 @@
                 
+ 
-%7D%0A
+   %7D%0A    
                 
@@ -2443,32 +2443,36 @@
             
+    
 %7D);%0A    
             
@@ -2455,24 +2455,369 @@
     %7D);%0A    
+            %7D catch (NullPointerException npe) %7B%0A                    // Work around for a race condition inside of the SCR runtime.%0A                    // In certain conditions, the SCR code gets an NPE due to a%0A                    // null bundle pointer%0A                    // Nothing we can do with the data, skip this entry%0A                %7D%0A
             

Work around race condition in SCR runtime when bundle pointer is null