blob: a78a8a985ad92049e5a0e89f0617c5ab9c47fa1b [file] [log] [blame]
/*
* 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.apache.felix.servicediagnostics.shell
import org.apache.felix.servicediagnostics.ServiceDiagnostics
import org.apache.felix.servicediagnostics.Util._
// old shell
import org.apache.felix.shell.Command
import java.io.PrintStream
// gogo shell
import org.apache.felix.service.command.Descriptor
class CLI extends Command
{
var engine:ServiceDiagnostics = _ //dependency injection. see Activator.
override def getName = "sd"
override def getShortDescription = "Service Diagnostics"
override def getUsage = "notavail|loops|using|providing|b2b"
// for gogo
def using = execute("sd using", System.out, System.err)
def providing = execute("sd providing", System.out, System.err)
def b2b = execute("sd b2b", System.out, System.err)
def notavail = execute("sd notavail", System.out, System.err)
def loops = execute("sd loops", System.out, System.err)
// for old shell
override def execute(commandLine:String, out:PrintStream, err:PrintStream) = commandLine.split(" ").toList.tail match {
case "using"::Nil =>
out.println(json(engine.usingBundles).toString(2))
case "providing"::Nil =>
out.println(json(engine.serviceProviders).toString(2))
case "b2b"::Nil =>
out.println(json(engine.b2b).toString(2))
case "notavail"::Nil =>
out.println(json(engine.notavail).toString(2))
case "loops"::Nil => showloops(out)
case _ => err.println(getUsage)
}
def showloops(out:PrintStream) = {
val unresolved = engine.unresolved(false) // map(comp -> list(comp))
out.println(json(unresolved).toString(2))
def follow(n:String, stack:Set[String] = Set()) :Set[String] =
if (stack contains n) stack
else unresolved.get(n) match {
case None => stack
case Some(list) => list.toSet.flatMap { (d:String) => follow(d, stack+n) }
}
unresolved.keySet.map(follow(_)).foreach { loop =>
if (loop.size > 1 && unresolved(loop.last) == loop.head)
out.println(loop.mkString("", " -> ", " -> "+loop.head))
}
}
}