From 6410c03640952f5c1edeb59b3def7b82888a0cf4 Mon Sep 17 00:00:00 2001 From: Peter Kriens Date: Fri, 14 Oct 2016 19:27:07 +0200 Subject: [PATCH] no time --- .../.classpath | 8 - .../.gitignore | 3 - .../.project | 23 - .../org.eclipse.core.resources.prefs | 9 - .../.settings/org.eclipse.jdt.core.prefs | 12 - osgi.enroute.command.enroute.provider/bnd.bnd | 42 -- .../readme.md | 15 - .../enroute/provider/FileCommands.java | 84 ---- .../enroute/provider/HelpCommands.java | 449 ------------------ .../command/enroute/provider/LogTracker.java | 358 -------------- .../enroute/provider/OSGiCommands.java | 416 ---------------- .../test/.gitignore | 0 12 files changed, 1419 deletions(-) delete mode 100644 osgi.enroute.command.enroute.provider/.classpath delete mode 100644 osgi.enroute.command.enroute.provider/.gitignore delete mode 100644 osgi.enroute.command.enroute.provider/.project delete mode 100644 osgi.enroute.command.enroute.provider/.settings/org.eclipse.core.resources.prefs delete mode 100644 osgi.enroute.command.enroute.provider/.settings/org.eclipse.jdt.core.prefs delete mode 100644 osgi.enroute.command.enroute.provider/bnd.bnd delete mode 100644 osgi.enroute.command.enroute.provider/readme.md delete mode 100644 osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/FileCommands.java delete mode 100644 osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/HelpCommands.java delete mode 100644 osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/LogTracker.java delete mode 100644 osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/OSGiCommands.java delete mode 100644 osgi.enroute.command.enroute.provider/test/.gitignore diff --git a/osgi.enroute.command.enroute.provider/.classpath b/osgi.enroute.command.enroute.provider/.classpath deleted file mode 100644 index 57c70f3..0000000 --- a/osgi.enroute.command.enroute.provider/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/osgi.enroute.command.enroute.provider/.gitignore b/osgi.enroute.command.enroute.provider/.gitignore deleted file mode 100644 index 11f90b6..0000000 --- a/osgi.enroute.command.enroute.provider/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/generated/ -/bin/ -/bin_test/ diff --git a/osgi.enroute.command.enroute.provider/.project b/osgi.enroute.command.enroute.provider/.project deleted file mode 100644 index 2c942b1..0000000 --- a/osgi.enroute.command.enroute.provider/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - osgi.enroute.command.enroute.provider - - - - - - org.eclipse.jdt.core.javabuilder - - - - - bndtools.core.bndbuilder - - - - - - org.eclipse.jdt.core.javanature - bndtools.core.bndnature - - diff --git a/osgi.enroute.command.enroute.provider/.settings/org.eclipse.core.resources.prefs b/osgi.enroute.command.enroute.provider/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index cb43b85..0000000 --- a/osgi.enroute.command.enroute.provider/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -encoding/.classpath=UTF-8 -encoding/.gitignore=UTF-8 -encoding/.project=UTF-8 -encoding//.settings/org.eclipse.jdt.core.prefs=UTF-8 -encoding//src/osgi/enroute/command/enroute/provider/OSGiCommands.java=UTF-8 -encoding//test/.gitignore=UTF-8 -encoding/bnd.bnd=UTF-8 -encoding/readme.md=UTF-8 diff --git a/osgi.enroute.command.enroute.provider/.settings/org.eclipse.jdt.core.prefs b/osgi.enroute.command.enroute.provider/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index a698e59..0000000 --- a/osgi.enroute.command.enroute.provider/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/osgi.enroute.command.enroute.provider/bnd.bnd b/osgi.enroute.command.enroute.provider/bnd.bnd deleted file mode 100644 index 8a23c2c..0000000 --- a/osgi.enroute.command.enroute.provider/bnd.bnd +++ /dev/null @@ -1,42 +0,0 @@ -# -# OSGI ENROUTE COMMAND ENROUTE PROVIDER BUNDLE -# - - -Bundle-Description: \ - Provides a number of commands that are dearly needed in Gogo. There is \ - special help support so type: `help` and you see all commands. Then type `help ` \ - for more info. If there a multiple commands with the same name in different scopes, you \ - can disambiguate them with :. - -Private-Package: \ - osgi.enroute.command.enroute.provider - -Conditional-Package: \ - aQute.lib* - --buildpath: \ - osgi.enroute.base.api;version=1.0,\ - org.apache.felix.gogo.runtime,\ - biz.aQute.bndlib;version=3.0; packages=* - --testpath: \ - osgi.enroute.junit.wrapper;version=4.12 - --includeresource: {readme.md} - - --runrequires: \ - osgi.identity;filter:='(osgi.identity=osgi.enroute.command.enroute.provider)',\ - osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.shell)' - --runbundles: \ - org.apache.felix.configadmin;version='[1.8.6,1.8.7)',\ - org.apache.felix.gogo.runtime;version='[0.16.2,0.16.3)',\ - org.apache.felix.gogo.shell;version='[0.12.0,0.12.1)',\ - org.apache.felix.log;version='[1.0.1,1.0.2)',\ - org.apache.felix.scr;version='[2.0.0,2.0.1)',\ - org.eclipse.equinox.metatype;version='[1.4.100,1.4.101)',\ - org.osgi.service.metatype;version='[1.3.0,1.3.1)',\ - osgi.enroute.command.enroute.provider;version=snapshot,\ - osgi.enroute.dtos.bndlib.provider;version=snapshot diff --git a/osgi.enroute.command.enroute.provider/readme.md b/osgi.enroute.command.enroute.provider/readme.md deleted file mode 100644 index 1486eef..0000000 --- a/osgi.enroute.command.enroute.provider/readme.md +++ /dev/null @@ -1,15 +0,0 @@ -# OSGI ENROUTE COMMAND ENROUTE PROVIDER - -${Bundle-Description} - -## Example - -## Configuration - - Pid: osgi.enroute.command.enroute - - Field Type Description - - -## References - diff --git a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/FileCommands.java b/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/FileCommands.java deleted file mode 100644 index 8cb409f..0000000 --- a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/FileCommands.java +++ /dev/null @@ -1,84 +0,0 @@ -package osgi.enroute.command.enroute.provider; - -import java.io.File; -import java.io.IOException; - -import org.apache.felix.service.command.CommandSession; -import org.apache.felix.service.command.Converter; -import org.apache.felix.service.command.Descriptor; -import org.osgi.service.component.annotations.Component; - -import aQute.lib.io.IO; -import osgi.enroute.debug.api.Debug; - -@Component(service = Object.class, name = "osgi.enroute.command.enroute.file", property = { Debug.COMMAND_SCOPE + "=enroute", - Debug.COMMAND_FUNCTION + "=cd", Debug.COMMAND_FUNCTION + "=ls", Debug.COMMAND_FUNCTION + "=vw" }) -public class FileCommands implements Converter { - - @Descriptor("Change work directory to the process work directory") - public String cd( CommandSession session) { - setCwd(session,IO.work); - return IO.work.getAbsolutePath(); - } - @Descriptor("Change directory from the current work directory") - public String cd( CommandSession session, @Descriptor("path") String path) { - File cwd = getCwd(session); - cwd = IO.getFile( cwd, path); - if ( !cwd.isDirectory()) - throw new IllegalArgumentException("Not a directory " + cwd); - - session.put("_pwd", cwd); - return cwd.getAbsolutePath(); - } - - - @Descriptor("List the files in the current directory") - public String[] ls(CommandSession session) { - return getCwd(session).list(); - } - - @Descriptor("List the contents of a file or directory. Use forward slashes for path") - public Object ls(CommandSession session, @Descriptor("path") String path) throws IOException { - File pwd = getCwd(session); - File f = IO.getFile(pwd, path); - if ( f.isDirectory()) - return f.list(); - else if ( f.isFile()) - return IO.collect(f); - else - return null; - } - - @Descriptor("View the contents of a file or directory (alias for ls)") - public Object vw(CommandSession session, String path) throws IOException { - return ls(session,path); - } - - @Override - public Object convert(Class arg0, Object arg1) throws Exception { - return null; - } - - @Override - public CharSequence format(Object object, int type, Converter all) throws Exception { - if ( object instanceof File) { - return object.toString(); - } - return null; - } - File getCwd(CommandSession session) { - File pwd = (File) session.get("_pwd"); - if ( pwd == null) - return IO.work; - else - return pwd; - } - File setCwd(CommandSession session, File file) { - if ( !file.isDirectory()) - throw new IllegalArgumentException("You can only set the working dir to a directory : " + file); - - session.put("_pwd", file); - return file; - } - -} diff --git a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/HelpCommands.java b/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/HelpCommands.java deleted file mode 100644 index f13ef36..0000000 --- a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/HelpCommands.java +++ /dev/null @@ -1,449 +0,0 @@ -package osgi.enroute.command.enroute.provider; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Formatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.felix.service.command.CommandSession; -import org.apache.felix.service.command.Converter; -import org.apache.felix.service.command.Descriptor; -import org.apache.felix.service.command.Function; -import org.apache.felix.service.command.Parameter; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; - -import aQute.lib.collections.MultiMap; -import aQute.lib.justif.Justif; -import aQute.lib.strings.Strings; -import aQute.libg.glob.Glob; -import osgi.enroute.debug.api.Debug; -import osgi.enroute.dto.api.DTOs; -import osgi.enroute.dto.api.TypeReference; - -@Descriptor("Provides help for Gogo commands") -@Component(name = "osgi.enroute.command.help", property = { Debug.COMMAND_SCOPE + "=help", - Debug.COMMAND_FUNCTION + "=help", Debug.COMMAND_FUNCTION + "=scope" }) -public class HelpCommands implements Converter { - - @Reference - DTOs dtos; - - BundleContext context = FrameworkUtil.getBundle(OSGiCommands.class).getBundleContext(); - static TypeReference> STRING_SET = new TypeReference>() { - }; - - class HelpScope { - String name; - String description; - Map commands = new HashMap<>(); - public List> references = new ArrayList<>(); - } - - class HelpCommand { - String scope; - String name; - List prototypes = new ArrayList<>();; - } - - class HelpCommandPrototype { - String description; - List options = new ArrayList<>(); - List arguments = new ArrayList<>(); - } - - class HelpOption { - String[] names; - boolean flag; - String deflt; - String type; - String description; - } - - @Descriptor("Show all scopes and their distinct command names") - public Collection help() throws Exception { - return getHelp("*").values(); - } - - @Descriptor("Inspect a scope") - public HelpScope scope(@Descriptor("scope")String scope) throws Exception { - Map help = getHelp(scope); - if (help.containsKey(scope)) - return help.get(scope); - return null; - } - - @Descriptor("Show the help for a specific function. You can specify the name of the function and optionally prefix it with the scope.") - public Object help(@Descriptor("[scope:]function") String function) throws Exception { - String scope = "*"; - if (function.indexOf(':') > 0) { - String parts[] = function.split(":"); - scope = parts[0]; - function = parts[1]; - } - - Map scopes = getHelp(scope); - if (scopes.containsKey(scope)) { - HelpScope s = scopes.get(scope); - return s.commands.get(function); - } - - // wildcard scope - Glob functionWildcard = new Glob(function); - - List commands = scopes.values().stream() // - .flatMap((HelpScope s) -> s.commands.values().stream()) // - .filter((HelpCommand f) -> functionWildcard.matcher(f.name).matches())// - .collect(Collectors.toList()); - - switch (commands.size()) { - case 0: - return scope(function); - case 1: - return commands.get(0); - default: - return commands.stream().map(f -> f.scope + ":" + f.name).collect(Collectors.toList()); - } - } - - private Map getHelp(String scope) throws Exception { - ServiceReference[] scopes = context.getServiceReferences((String) null, - "(" + Debug.COMMAND_SCOPE + "=" + scope + ")"); - - if (scopes == null) - scopes = new ServiceReference[0]; - - Map map = new HashMap<>(); - Stream.of(scopes).map(this::toHelpScope).forEach((s) -> { - HelpScope prev = map.get(s.name); - if (prev == null) - map.put(s.name, s); - else - merge(prev, s); - }); - return map; - } - - private void merge(HelpScope prev, HelpScope next) { - prev.description = mergeDescription(prev.description, next.description); - - for (Entry e : next.commands.entrySet()) { - HelpCommand hc = prev.commands.get(e.getKey()); - if (hc == null) - prev.commands.put(e.getKey(), e.getValue()); - else - merge(hc, e.getValue()); - } - } - - private String mergeDescription(String a, String b) { - if (a != null && b != null) - return a + "\n" + b; - - if (a != null) - return a; - else - return b; - } - - private void merge(HelpCommand a, HelpCommand b) { - a.prototypes.addAll(b.prototypes); - } - - private HelpScope toHelpScope(ServiceReference ref) { - Object service = context.getService(ref); - if (service == null) - return null; - - try { - HelpScope scope = new HelpScope(); - scope.references.add(ref); - scope.name = (String) ref.getProperty(Debug.COMMAND_SCOPE); - Descriptor descriptor = service.getClass().getAnnotation(Descriptor.class); - if (descriptor != null) - scope.description = descriptor.value(); - - Set names = dtos.convert(ref.getProperty(Debug.COMMAND_FUNCTION)).to(STRING_SET); - - MultiMap allMethods = getMethods(service.getClass()); - - for (String name : names) { - HelpCommand command = new HelpCommand(); - command.name = name; - command.scope = scope.name; - - List methods = allMethods.get(name); - if (methods == null || methods.isEmpty()) - continue; - - for (Method method : methods) - command.prototypes.add(getPrototype(method)); - - scope.commands.put(name, command); - } - return scope; - - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - context.ungetService(ref); - } - } - - private MultiMap getMethods(Class c) { - MultiMap methods = new MultiMap<>(); - - for (Method m : c.getMethods()) { - methods.add(m.getName(), m); - } - return methods; - } - - private HelpCommandPrototype getPrototype(Method m) { - HelpCommandPrototype help = new HelpCommandPrototype(); - - Descriptor description = m.getAnnotation(Descriptor.class); - if (description != null) - help.description = description.value(); - - Annotation[][] annotations = m.getParameterAnnotations(); - Type[] arguments = m.getGenericParameterTypes(); - for (int i = 0; i < arguments.length; i++) { - Annotation[] argAnns = annotations[i]; - Type type = arguments[i]; - if (type == CommandSession.class) - continue; - - Optional descr = find(argAnns, Descriptor.class); - HelpOption helpOption = helpOption(type, descr, find(argAnns, Parameter.class)); - if (helpOption != null) { - help.options.add(helpOption); - } else { - String varargs = ""; - if (isVarargs(m, arguments, i, type)) { - varargs = "…"; - type = String.class; - } - - String name; - if (descr.isPresent()) - name = "<"+descr.get().value()+">"+varargs ; - else if (type == Function.class) - name = "{}" + varargs; - else if (type == Object.class) - name = "any"+varargs; - else if (type == String.class) - name = "_"+varargs; - else - name = "<"+toShortName(type)+">"+varargs ; - - - help.arguments.add(name); - } - } - return help; - } - - private boolean isVarargs(Method m, Type[] arguments, int i, Type type) { - return i == arguments.length - 1 && (m.isVarArgs() || (type instanceof Class && ((Class) type).isArray())); - } - - private HelpOption helpOption(Type type, Optional description, Optional parameter) { - if (!parameter.isPresent()) - return null; - - HelpOption option = new HelpOption(); - option.names = parameter.get().names(); - option.flag = !parameter.get().presentValue().equals(Parameter.UNSPECIFIED); - option.deflt = parameter.get().absentValue(); - option.type = toShortName(type); - if (description.isPresent()) - option.description = description.get().value(); - - return option; - } - - private Optional find(Annotation[] annotations, Class annotationType) { - Optional findFirst = Stream.of(annotations)// - .filter(a -> annotationType.isInstance(a))// - .map(a -> annotationType.cast(a)).findFirst(); - return findFirst; - } - - String toCommands(ServiceReference sr) { - try { - StringBuilder sb = new StringBuilder((String) sr.getProperty(Debug.COMMAND_SCOPE)); - String del = " : "; - ArrayList l = dtos.convert(sr.getProperty(Debug.COMMAND_FUNCTION)).to(ArrayList.class); - for (Object o : l) { - sb.append(del).append(o); - del = ", "; - } - return sb.toString(); - } catch (Exception e) { - return e.getMessage(); - } - } - - private String toShortName(Type type) { - if (type instanceof Class) { - Class c = (Class) type; - if (c.isArray()) - return toShortName(c.getComponentType()) + "[]"; - toShortName(c.getName()); - } - - return toShortName(type.toString()); - } - - private String toShortName(String oc) { - int n = oc.lastIndexOf('.'); - return oc.substring(n + 1); - } - - - @Override - public Object convert(Class arg0, Object arg1) throws Exception { - return null; - } - - @Override - public CharSequence format(Object help, int type, Converter arg2) throws Exception { - Justif justif = new Justif(80, 10, 40, 42, 44, 48, 50, 52); - Formatter f = justif.formatter(); - try { - if (help instanceof HelpScope) { - switch (type) { - case Converter.INSPECT: - inspect(f, (HelpScope) help); - break; - - case Converter.LINE: - line(f, (HelpScope) help); - break; - - case Converter.PART: - part(f, (HelpScope) help); - break; - } - return justif.wrap(); - } else if (help instanceof HelpCommand) { - switch (type) { - case Converter.INSPECT: - inspect(f, (HelpCommand) help); - break; - case Converter.LINE: - line(f, (HelpCommand) help); - break; - - case Converter.PART: - part(f, (HelpCommand) help); - break; - } - return justif.wrap(); - } else - return null; - } finally { - f.close(); - } - } - - private void part(Formatter f, HelpScope help) { - f.format("%s", help.name); - } - - private void line(Formatter f, HelpScope help) { - String s = Strings.join(", ",help.commands.keySet()); - f.format("%s\t1: \t2%s", help.name, s); - } - - private void inspect(Formatter f, HelpScope help) { - f.format("SCOPE\n"); - f.format(" %s\n\n", help.name); - if (help.description != null) { - f.format("DESCRIPTION\n"); - f.format(" %s\n\n", help.description); - } - f.format("COMMANDS\n"); - for (HelpCommand cmd : help.commands.values()) { - line(f, cmd); - } - - } - - private void part(Formatter f, HelpCommand help) { - f.format("%s", help.name); - } - - private void line(Formatter f, HelpCommand help) { - StringBuilder sb = new StringBuilder(); - help.prototypes.stream()// - .flatMap((HelpCommandPrototype p) -> p.options.stream()) // - .flatMap((HelpOption o) -> Stream.of(o.names)) // - .filter(s -> s.matches("-[^-]")) // - .forEach(s -> sb.append(s.charAt(1))); - - f.format( "%s\t2-\t3", help.name); - int n = 1; - for ( HelpCommandPrototype hcp : help.prototypes) { - f.format("%s. %s\f",n,hcp.description); - n++; - } - f.format("\n"); - } - - - private void inspect(Formatter f, HelpCommand help) { - f.format("NAME\n"); - f.format(" [%s:]%s\n\n", help.scope, help.name); - - f.format("PROTOTYPES\n"); - for (HelpCommandPrototype p : help.prototypes) { - f.format(" %s ", help.name); - line( f, p); - } - } - - private void line(Formatter f, HelpCommandPrototype p) { - String del = ""; - if ( !p.options.isEmpty()) { - f.format(" [options] "); - } - del = args(f, p, del); - if ( p.description != null) - f.format("\t2-\t3%s", p.description); - - f.format("\n"); - - for( HelpOption option : p.options) { - if ( option.flag) { - f.format(" %s[%s]", del,Strings.join(",", option.names)); - } else { - f.format(" %s[%s (%s)]", del,Strings.join(",", option.names), option.deflt); - } - del = " "; - f.format("\t2-\t3%s\n", option.description == null ? "" : option.description); - } - } - - private String args(Formatter f, HelpCommandPrototype p, String del) { - for( String arg : p.arguments) { - f.format("%s%s", del, arg); - del =" "; - } - return del; - } -} diff --git a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/LogTracker.java b/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/LogTracker.java deleted file mode 100644 index 5b5625b..0000000 --- a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/LogTracker.java +++ /dev/null @@ -1,358 +0,0 @@ -package osgi.enroute.command.enroute.provider; - -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.Formatter; -import java.util.List; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.ServiceReference; -import org.osgi.service.log.LogEntry; -import org.osgi.service.log.LogListener; -import org.osgi.service.log.LogReaderService; -import org.osgi.service.log.LogService; -import org.osgi.util.tracker.ServiceTracker; - -/** - * This class provides a listener for the log service so that clients can decide - * how big the buffer is. Valentin Valchev gave some good hints: - *

- * 1. You have a bundle with native code - there is an exception class declared - * in that bundle - the exception is thrown somewhere and logged - if the log - * entry, with the exception above is inside the log queue, the bundle update - * will fail the reason is that the class loader of the first version of the - * bundle cannot be discarded, so the native library is not unloaded. When the - * new version is installed, and tries to load the native library it will fails, - * because the library is already loaded. ! the solution is to use the method - * mentioned by LogReaderService.getLog() - to wrap the exception so you don't - * keep references to the original exception - *

- * 2. If you are using IBM J9/VAME virtual machine : - you may throw and log - * IOException as example - in that case your bundle becomes part of the stack - * trace - your bundle is updated or uninstalled - another bundle uses the log - * reader to get the exceptions - when that bundle gets the IOException and - * tries to print the stack trace the virtual machine dies ! the solution is - * same as above - *

- * To prevent the aforementioned problems we print the stack trace and store it - * in the log as a string. - */ -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class LogTracker extends ServiceTracker implements Runnable { - /** - * Max number of entries in the buffer - */ - final int SIZE = 200; - - /* - * Used to extract the first line of the stack trace - */ - private static Pattern FIRST_LINE_P = Pattern.compile("^([^\n\r]{0,80})"); - - final BundleContext context; - final ConcurrentLinkedDeque list = new ConcurrentLinkedDeque(); - final LinkedBlockingQueue queue = new LinkedBlockingQueue(100); - final Thread thread = new Thread(this, "Apache Felix::Log Listener"); - - private List consoles = new CopyOnWriteArrayList<>(); - - /** - * Log Level - Aligned with the OSGi Log levels (i.e. ordinal == OSGi) - */ - public enum Level { - unknown, error, warning, info, debug - } - - /** - * Print style - */ - public enum Style { - classic, abbr; - } - - /** - * DTO to hold the serialized information about a log entry - */ - static class LE { - int id; - String message; - String exception; - Level level; - long serviceId = -1; - String service; - long time; - String bundle; - long bundleId; - - } - - /** - * Constructor - * - */ - public LogTracker(BundleContext context) { - super(context, LogReaderService.class.getName(), null); - this.context = context; - super.open(); - thread.start(); - } - - /** - * Get rid of our thread - */ - - public void close() { - thread.interrupt(); - } - - /** - * Tracks Log Services. Will merge all records if there are several. - */ - public Object addingService(ServiceReference ref) { - LogReaderService lrs = (LogReaderService) super.addingService(ref); - lrs.addLogListener(new LogListener() { - - public void logged(LogEntry entry) { - queue.offer(entry); - } - - }); - Enumeration e = lrs.getLog(); - while (e.hasMoreElements()) - queue.offer(e.nextElement()); - - return lrs; - } - - /** - * Background thread to convert Log Entry records to a form that is not - * holding any references. - */ - public void run() { - - int currentId = 1000; - - try { - while (!thread.isInterrupted()) { - - // - // We block until we get an entry or are interrupted - // - - LogEntry entry = queue.take(); - - - - - // - // Get the data in a non-reference form - // - - LE le = new LE(); - le.id = currentId++; - le.message = entry.getMessage(); - le.level = getLevel(entry.getLevel()); - le.time = entry.getTime(); - - Bundle b = entry.getBundle(); - if (b != null) { - le.bundleId = entry.getBundle().getBundleId(); - le.bundle = entry.getBundle().getSymbolicName(); - } - if (entry.getServiceReference() != null) { - le.serviceId = (Long) entry.getServiceReference().getProperty(Constants.SERVICE_ID); - le.service = entry.getServiceReference().toString(); - } - - if (entry.getException() != null) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - entry.getException().printStackTrace(pw); - pw.close(); - le.exception = sw.toString(); - } - - for ( PrintStream console : consoles) try { - Formatter f = new Formatter(); - abbr(f,le,true); - console.println( f.toString()); - } catch( Exception e){ - // ignore - } - list.add(le); - - // - // Shrink the list if it gets too long - // - - if (list.size() > SIZE) - list.removeLast(); - - } - } catch (InterruptedException ie) { - // ok, we're done here - } - } - - /* - * Convert an integer level to the enum - */ - private Level getLevel(int level) { - switch (level) { - case LogService.LOG_ERROR: - return Level.error; - case LogService.LOG_WARNING: - return Level.warning; - case LogService.LOG_INFO: - return Level.info; - default: - return Level.debug; - } - } - - /* - * Select the entries from the log. - * - * @param maxEntries Max number of matching entries to fetch - * - * @param skip Number of entries to skip - * - * @param logLevel The minimum level - * - * @param reverse Return a reversed list or not - * - * @return a filtered list - */ - public List select(int maxEntries, int skip, Level logLevel, boolean reverse) { - - List result = new ArrayList(); - - for (LE entry : list) { - - if (entry.level.compareTo(logLevel) > 0) - continue; - - if (skip-- > 0) - continue; - - if (maxEntries-- <= 0) - break; - - result.add(entry); - } - - if (reverse) - Collections.reverse(result); - - return result; - } - - /** - * Entry method to get the log. Lots of options - * - * @param maxEntries - * Max number of matching entries to fetch - * @param skip - * Number of entries to skip - * @param logLevel - * The minimum level - * @param reverse - * Return a reversed list or not - * @param noExceptions - * Do not print exceptions - * @param style - * Different print styles - * @return a formatted list - */ - public List log(int maxEntries, int skip, Level logLevel, boolean reverse, boolean noExceptions, - Style style) { - - List selected = select(maxEntries, skip, logLevel, reverse); - List result = new ArrayList(selected.size()); - - StringBuilder sb = new StringBuilder(); - Formatter f = new Formatter(sb); - try { - for (LE entry : selected) { - - // - // Clear the buffer, we reuse one buffer for efficiency - // - - sb.setLength(0); - - switch (style) { - case abbr: - abbr(f, entry, noExceptions); - break; - - default: - classic(f, entry, noExceptions); - break; - } - f.flush(); - result.add(sb.toString()); - } - } finally { - f.close(); - } - return result; - } - - /* - * Classic formatting - */ - private void classic(Formatter f, LE entry, boolean noExceptions) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); - f.format("%s %s - Bundle: %s", sdf.format(new Date(entry.time)), entry.level, entry.bundle); - - if (entry.serviceId != -1) { - f.format(" - %s", entry.service); - } - - f.format(" - %s", entry.message); - - if (entry.exception != null && !noExceptions) { - f.format(" - %s", entry.exception); - } - } - - /* - * Abbreviated formatting - */ - private void abbr(Formatter f, LE entry, boolean noExceptions) { - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); - String firstLine = ""; - if (entry.exception != null) { - Matcher matcher = FIRST_LINE_P.matcher(entry.exception); - if (matcher.find()) - firstLine = matcher.group(1); - } - - f.format("%4d %s %-6s %-40s %s %s", entry.id, sdf.format(new Date(entry.time)), entry.level, entry.bundle, - entry.message, firstLine); - } - - public void addConsole(PrintStream console) { - consoles .add(console); - - } - - public void removeConsole(PrintStream console) { - consoles .add(console); - - } -} diff --git a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/OSGiCommands.java b/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/OSGiCommands.java deleted file mode 100644 index 641187b..0000000 --- a/osgi.enroute.command.enroute.provider/src/osgi/enroute/command/enroute/provider/OSGiCommands.java +++ /dev/null @@ -1,416 +0,0 @@ -package osgi.enroute.command.enroute.provider; - -import java.io.IOException; -import java.io.PrintStream; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Formatter; -import java.util.List; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.felix.service.command.CommandSession; -import org.apache.felix.service.command.Descriptor; -import org.apache.felix.service.command.Parameter; -import org.osgi.dto.DTO; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.FrameworkEvent; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.wiring.FrameworkWiring; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.runtime.ServiceComponentRuntime; -import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO; -import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO; -import org.osgi.service.log.LogService; - -import aQute.libg.glob.Glob; -import osgi.enroute.command.enroute.provider.LogTracker.Level; -import osgi.enroute.debug.api.Debug; -import osgi.enroute.dto.api.DTOs; -import osgi.enroute.dto.api.TypeReference; - -/** - * - */ -@Component(service = Object.class, name = "osgi.enroute.command.enroute.osgi", property = { Debug.COMMAND_SCOPE + "=enroute", - Debug.COMMAND_FUNCTION + "=log", Debug.COMMAND_FUNCTION + "=lss", Debug.COMMAND_FUNCTION + "=logerror", - Debug.COMMAND_FUNCTION + "=start", Debug.COMMAND_FUNCTION + "=stop", Debug.COMMAND_FUNCTION + "=lsb", Debug.COMMAND_FUNCTION + "=lsc", - Debug.COMMAND_FUNCTION + "=refresh" }) -public class OSGiCommands { - - static class PackageDTO extends DTO { - public String name; - public String version; - public Bundle exportedBy; - public List importedBy = new ArrayList<>(); - } - BundleContext context = FrameworkUtil.getBundle(OSGiCommands.class).getBundleContext(); - static TypeReference> stringlist = new TypeReference>() { - }; - private LogTracker logTracker; - - @Reference - DTOs dtos; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - LogService log; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - ServiceComponentRuntime ds; - - @Activate - void act(BundleContext context) { - logTracker = new LogTracker(context); - logTracker.open(); - } - - @Deactivate - void deact(BundleContext context) { - logTracker.close(); - } - - /** - * List services - * - * @param v - * use the glob as not - * @param bundleId - * the bundle id to look for or -1 for all - * @param g - * the glob expression - * @param keys - * any keys that should be listed from the properties - * @return a list of strings - * @throws Exception - */ - @Descriptor("List services and optionally filter them for keywords. Specifying property keys limts the output to those keys.") - public List lss(// - @Descriptor("Reverse they keyword filter match") // - @Parameter(names = { "-v", "--not" }, presentValue = "true", absentValue = "false") boolean v, // - @Descriptor("Only show services of the given bundle") @Parameter(names = { "-b", - "--bundle" }, absentValue = "-1") long bundleId, // - @Descriptor("filter") Glob g, @Descriptor("key") String... keys) throws Exception - - { - ArrayList sb = new ArrayList<>(); - ArrayList columns = new ArrayList<>(); - for (String key : keys) { - columns.add(new Glob(key)); - } - - ServiceReference[] refs = context.getAllServiceReferences(null, null); - if (refs != null) { - for (ServiceReference ref : refs) { - - if (bundleId >= 0 && ref.getBundle().getBundleId() != bundleId) - continue; - - Formatter sub = new Formatter(); - try { - String[] objectClass = (String[]) ref.getProperty(Constants.OBJECTCLASS); - String del = ", "; - for (String oc : objectClass) { - sub.format("%-24s", toShortName(oc)); - } - del = " : "; - for (String key : ref.getPropertyKeys()) { - - if (columns.isEmpty() || has(columns, key)) { - sub.format("%s%s=%s", del, key, toString(ref.getProperty(key))); - del = ", "; - } - } - String s = sub.toString(); - if (g.matcher(s).find() == !v) - sb.add(s); - } finally { - sub.close(); - } - } - } - return sb; - } - - private String toShortName(String oc) { - int n = oc.lastIndexOf('.'); - return oc.substring(n + 1); - } - - private boolean has(ArrayList columns, String key) { - for (Glob g : columns) { - if (g.matcher(key).matches()) - return true; - } - return false; - } - - private String toString(Object o) throws Exception { - if (o == null) - return "null"; - - return dtos.convert(o).to(String.class).toString(); - } - - @Descriptor("List all registered services") - public List lss() throws Exception { - return lss(false, -1, new Glob("*")); - } - - @Descriptor("List all services of the given bundle-id") - public List lss(@Descriptor("bundle-id") int bundleId) throws Exception { - return lss(false, bundleId, new Glob("*")); - } - - /** - * List log - * - * @param reverse - * @param skip - * @param maxEntries - * @param level - * @param style - * @param noExceptions - * @return - * @throws IOException - */ - @Descriptor("Show the contents of the log") - public List log( - // - CommandSession session, @Descriptor("Tail the log") // - @Parameter(names = { "-t", "--tail" }, presentValue = "true", absentValue = "false") boolean tail, // - @Descriptor("Reverse the printout order to oldest is last") // - @Parameter(names = { "-r", "--reverse" }, absentValue = "true", presentValue = "false") boolean reverse, // - // - @Descriptor("Skip the first entries") // - @Parameter(names = { "-s", "--skip" }, absentValue = "0") int skip, // - - // - @Descriptor("Maximum number of entries to print") // - @Parameter(names = { "-m", "--max" }, absentValue = "100") int maxEntries, // - @Descriptor("Minimum level (error,warning,info,debug). Default is warning.") // - @Parameter(names = { "-l", "--level" }, absentValue = "warning") String level, // - @Descriptor("Print style (classic,abbr)") // - @Parameter(names = { "-y", "--style" }, absentValue = "classic") String style, // - @Descriptor("Do not print exceptions.") @Parameter(names = { "-n", - "--noexceptions" }, absentValue = "false", presentValue = "true") boolean noExceptions // - ) throws IOException { - if (tail) { - logtail(session); - return null; - } - - return logTracker.log(maxEntries, skip, toLogLevel(level), reverse, noExceptions, - LogTracker.Style.valueOf(style)); - } - - private Level toLogLevel(String logLevel) { - return LogTracker.Level.valueOf(logLevel.toLowerCase()); - } - - @Descriptor("Tail the log") - public void logtail(CommandSession session) throws IOException { - PrintStream console = session.getConsole(); - logTracker.addConsole(console); - try { - byte[] data = new byte[1]; - session.getKeyboard().read(data); - } catch (Throwable e) { - e.printStackTrace(); - } finally { - logTracker.removeConsole(console); - } - } - - @Descriptor("Generate an error in the log") - public void logerror(@Descriptor("message") String foo) throws Exception { - log.log(LogService.LOG_ERROR, foo); - } - - @Descriptor("List bundles") - public Collection lsb( - @Descriptor("Show active bundles") @Parameter(names = { "-a", - "--active" }, presentValue = "true", absentValue = "false") boolean active, - @Descriptor("Show installed bundles") @Parameter(names = { "-i", - "--installed" }, presentValue = "true", absentValue = "false") boolean installed, - @Descriptor("Show uninstalled bundles") @Parameter(names = { "-r", - "--resolved" }, presentValue = "true", absentValue = "false") boolean resolved, - @Descriptor("Show uninstalled bundles") @Parameter(names = { "-u", - "--uninstalled" }, presentValue = "true", absentValue = "false") boolean uninstalled, - @Descriptor("Show starting/stopping bundles") @Parameter(names = { "-s", - "--startingOrStopping" }, presentValue = "true", absentValue = "false") boolean changing - - ) { - int state = 0; - if (active) - state |= Bundle.ACTIVE; - if (installed) - state |= Bundle.INSTALLED; - if (resolved) - state |= Bundle.RESOLVED; - if (uninstalled) - state |= Bundle.UNINSTALLED; - if (changing) - state |= Bundle.STARTING | Bundle.STOPPING; - - if (state == 0) - state = 0xFFFF_FFFF; - final int effectiveState = state; - - return Stream.of(context.getBundles()).filter(b -> (b.getState() & effectiveState) != 0) - .collect(Collectors.toList()); - } - - @Descriptor("Start one or more bundles, if none specified, start all non-active bundles.") - public Collection start( // - @Descriptor("Start option. 1=START_TRANSIENT and 2=START_ACTIVATION_POLICY, -1 no options") // - @Parameter(names = { "-o", "--option" }, absentValue = "-1") int option, @Descriptor("id") long... ids) { - List bundles = new ArrayList<>(); - Arrays.sort(ids); - - for (Bundle b : context.getBundles()) { - if (b.getState() == Bundle.INSTALLED || b.getState() == Bundle.RESOLVED) { - if (ids.length == 0 || in(ids, b.getBundleId())) { - try { - if (option > 0) - b.start(option); - else - b.start(); - - bundles.add(b); - } catch (Exception e) { - System.err.println(b + " : " + e.getMessage()); - } - } - } - } - - return bundles; - } - - @Descriptor("Stop one or more bundles, if none specified stop all active bundles") - public Collection stop(@Descriptor("Start option. 1=STOP_TRANSIENT, -1 no options") // - @Parameter(names = { "-o", "--option" }, absentValue = "-1") int option, // - @Descriptor("id") long... ids) { - List bundles = new ArrayList<>(); - Arrays.sort(ids); - - for (Bundle b : context.getBundles()) { - if (b.getState() == Bundle.ACTIVE) { - if (ids.length == 0 || in(ids, b.getBundleId())) { - try { - if (option > 0) - b.stop(option); - else - b.stop(); - - bundles.add(b); - } catch (Exception e) { - System.err.println(b + " : " + e.getMessage()); - } - } - } - } - - return bundles; - } - - @Descriptor("Refresh a set of bundles") - public String refresh(CommandSession session, - @Descriptor("Quiet") @Parameter(names = {"-q", "--quiet"}, absentValue = "false", presentValue = "true") boolean quiet, - @Descriptor("Wait for the refresh to finish") @Parameter(names = {"-w", "--wait"}, absentValue = "false", presentValue = "true") boolean wait, - Bundle ... bundles) { - FrameworkWiring fw = context.getBundle(0).adapt(FrameworkWiring.class); - List bs = Stream.of(bundles).collect(Collectors.toList()); - if (wait) { - Semaphore s = new Semaphore(0); - fw.refreshBundles(bs, (FrameworkEvent e) -> s.release()); - try { - if (!quiet) - session.getConsole().println("will wait for refresh to finish (max 3 mins)"); - s.tryAcquire(3, TimeUnit.MINUTES); - if (!quiet) - return "done"; - } catch (InterruptedException e1) { - if (quiet) - return null; - return "Interrupted"; - } - } else if (!quiet) { - fw.refreshBundles(bs, (FrameworkEvent e) -> session.getConsole().println("Finished refreshing")); - return "Will signal when refresh is done"; - } - return null; - } - - private boolean in(long[] ids, long id) { - return Arrays.binarySearch(ids, id) >= 0; - } - - public List lsc() { - return ds.getComponentDescriptionDTOs().stream().map(d -> d.name).collect(Collectors.toList()); - } - - public List lsc( - @Parameter(names = { "-c", "--configuration" }, absentValue = "false", presentValue = "true") boolean conf, - @Parameter(names = { "-i", "--id" }, absentValue = "-1") long id, Glob g) { - return ds.getComponentDescriptionDTOs().stream().filter(r -> g.matcher(r.name).matches()).map(d -> { - Formatter sw = new Formatter(); - try { - ComponentDescriptionDTO cdd = d; - print(sw, cdd); - if (conf) { - Collection c = ds.getComponentConfigurationDTOs(d); - for (ComponentConfigurationDTO ccd : c) { - - if (id >= 0 && id != ccd.id) - continue; - - sw.format("--- %s ---\n", ccd.id); - print(sw, ccd); - } - sw.format("---------------------\n"); - } - return sw.toString(); - } finally { - sw.close(); - } - }).collect(Collectors.toList()); - } - - private void print(Formatter sw, DTO c) { - for (Field f : c.getClass().getFields()) - - try { - if (Modifier.isStatic(f.getModifiers())) - continue; - - sw.format("%-40s %s\n", toUpper(f.getName()), format(f.get(c))); - } catch (Exception e) { - sw.format("%-40s %s\n", toUpper(f.getName()), e.getMessage()); - } - } - - private String format(Object object) { - if (object.getClass().isArray()) - return Arrays.toString((Object[]) object); - - return object + ""; - } - - private Object toUpper(String name) { - return Character.toUpperCase(name.charAt(0)) + name.substring(1); - } - -} diff --git a/osgi.enroute.command.enroute.provider/test/.gitignore b/osgi.enroute.command.enroute.provider/test/.gitignore deleted file mode 100644 index e69de29..0000000