Initial commit of mishell. Mishell is a scripting environment and console for remote jmx management.
See README.txt for details.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@442641 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/mishell/src/main/java/org/apache/felix/mishell/Activator.java b/mishell/src/main/java/org/apache/felix/mishell/Activator.java
new file mode 100644
index 0000000..a879a69
--- /dev/null
+++ b/mishell/src/main/java/org/apache/felix/mishell/Activator.java
@@ -0,0 +1,31 @@
+package org.apache.felix.mishell;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private Console console;
+
+ public void start(BundleContext context) throws Exception {
+
+ //NOTE: new javax.script.EngineManager() uses context class loader
+ //We've changed that to use EngineManager(ClassLoader loader)
+ //Alternatively, we could instantiate it in a separate thread with proper context class loader set.
+ console = new Console("javascript", null);
+ Thread t=new Thread(console);
+ //At least JRuby engine (maybe others too) uses context class loaders internally
+ //So this is to prevent problems with that: context cl=console class loader which in turn
+ //loads the manager and therefore engine factory
+ t.setContextClassLoader(this.getClass().getClassLoader());
+ t.setName("ConsoleThread");
+ t.start();
+
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ console.stop();
+
+ }
+
+}
diff --git a/mishell/src/main/java/org/apache/felix/mishell/Command.java b/mishell/src/main/java/org/apache/felix/mishell/Command.java
new file mode 100644
index 0000000..648428e
--- /dev/null
+++ b/mishell/src/main/java/org/apache/felix/mishell/Command.java
@@ -0,0 +1,9 @@
+package org.apache.felix.mishell;
+
+import java.io.PrintStream;
+
+public interface Command {
+ public void executeCommand(String cmd, PrintStream out) throws Exception;
+ public String getName();
+ public String getHelp();
+}
diff --git a/mishell/src/main/java/org/apache/felix/mishell/CommandNotFoundException.java b/mishell/src/main/java/org/apache/felix/mishell/CommandNotFoundException.java
new file mode 100644
index 0000000..9da9126
--- /dev/null
+++ b/mishell/src/main/java/org/apache/felix/mishell/CommandNotFoundException.java
@@ -0,0 +1,5 @@
+package org.apache.felix.mishell;
+
+public class CommandNotFoundException extends Exception {
+
+}
diff --git a/mishell/src/main/java/org/apache/felix/mishell/EngineNotFoundException.java b/mishell/src/main/java/org/apache/felix/mishell/EngineNotFoundException.java
new file mode 100644
index 0000000..3e8b05b
--- /dev/null
+++ b/mishell/src/main/java/org/apache/felix/mishell/EngineNotFoundException.java
@@ -0,0 +1,9 @@
+package org.apache.felix.mishell;
+
+public class EngineNotFoundException extends Exception {
+
+ public EngineNotFoundException(String language) {
+ super(language);
+ }
+
+}
diff --git a/mishell/src/main/java/org/apache/felix/mishell/JMoodProxyManager.java b/mishell/src/main/java/org/apache/felix/mishell/JMoodProxyManager.java
new file mode 100644
index 0000000..73a545f
--- /dev/null
+++ b/mishell/src/main/java/org/apache/felix/mishell/JMoodProxyManager.java
@@ -0,0 +1,27 @@
+package org.apache.felix.mishell;
+
+import java.util.List;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.felix.jmxintrospector.MBean;
+import org.apache.felix.jmxintrospector.MBeanProxyManager;
+
+public class JMoodProxyManager extends MBeanProxyManager {
+ public List<Object> getControllers(){
+ return findAll("type=controller");
+ }
+ public List<Object> getBundlesAt(Object controller){
+ MBeanServerConnection server=((MBean)controller).getMBeanServer();
+ return findAll("type=bundle", server);
+ }
+ public List<Object> getServicesAt(Object controller){
+ MBeanServerConnection server=((MBean)controller).getMBeanServer();
+ return findAll("type=service", server);
+ }
+ public List<Object> getPackagesAt(Object controller){
+ MBeanServerConnection server=((MBean)controller).getMBeanServer();
+ return findAll("type=package", server);
+ }
+
+}
diff --git a/mishell/src/main/resources/logging.properties b/mishell/src/main/resources/logging.properties
new file mode 100644
index 0000000..65f94dd
--- /dev/null
+++ b/mishell/src/main/resources/logging.properties
@@ -0,0 +1,54 @@
+############################################################
+# Default Logging Configuration File
+#
+# You can use a different file by specifying a filename
+# with the java.util.logging.config.file system property.
+# For example java -Djava.util.logging.config.file=myfile
+############################################################
+
+############################################################
+# Global properties
+############################################################
+
+# "handlers" specifies a comma separated list of log Handler
+# classes. These handlers will be installed during VM startup.
+# Note that these classes must be on the system classpath.
+# By default we only configure a ConsoleHandler, which will only
+# show messages at the INFO and above levels.
+handlers= java.util.logging.ConsoleHandler
+
+# To also add the FileHandler, use the following line instead.
+#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+
+# Default global logging level.
+# This specifies which kinds of events are logged across
+# all loggers. For any given facility this global level
+# can be overriden by a facility specific level
+# Note that the ConsoleHandler also has a separate level
+# setting to limit messages printed to the console.
+.level= FINEST
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+# default file output is in user's home directory.
+java.util.logging.FileHandler.pattern = %h/java%u.log
+java.util.logging.FileHandler.limit = 50000
+java.util.logging.FileHandler.count = 1
+java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
+
+# Limit the message that are printed on the console to INFO and above.
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+com.xyz.foo.level = SEVERE
diff --git a/mishell/src/test/java/org/apache/felix/mishell/FelixLauncher.java b/mishell/src/test/java/org/apache/felix/mishell/FelixLauncher.java
new file mode 100644
index 0000000..d2a085f
--- /dev/null
+++ b/mishell/src/test/java/org/apache/felix/mishell/FelixLauncher.java
@@ -0,0 +1,157 @@
+package org.apache.felix.mishell;
+/*
+ * Copyright 2005 The Apache Software 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.
+ *
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.felix.framework.Felix;
+import org.apache.felix.framework.util.MutablePropertyResolver;
+import org.apache.felix.framework.util.MutablePropertyResolverImpl;
+import org.osgi.framework.Constants;
+public class FelixLauncher {
+
+ private MutablePropertyResolver props;
+ private Felix framework;
+ private List bundles;
+ private List packages;
+ private File cacheDir;
+ public FelixLauncher() {
+ super();
+ cacheDir = new File("./cache");
+ System.out.println(cacheDir.getAbsolutePath());
+ clearCache(cacheDir);
+ cacheDir.mkdir();
+
+ framework = new Felix();
+ Map m=new HashMap();
+ bundles=new ArrayList();
+ packages=new ArrayList();
+
+ props = new MutablePropertyResolverImpl(m);
+ props.put("felix.cache.profiledir", cacheDir.getAbsolutePath());
+
+ }
+ public void addBundle(String url){
+ if (!bundles.contains(url))
+ bundles.add(url);
+ }
+ public void addPackage(String packageName){
+ if(!packages.contains(packageName))
+ packages.add(packageName);
+ }
+ public void start(){
+ StringBuffer autostart=new StringBuffer();
+ for (int i=0; i<bundles.size(); i++){
+ String bundle=(String)bundles.get(i);
+ autostart.append(bundle).append(" ");
+ }
+ props.put("felix.auto.start.1", autostart.toString());
+ StringBuffer spkg=new StringBuffer((String)packages.get(0));
+ packages.remove(0);
+ for (int i=0; i<packages.size(); i++){
+ String pkg=(String)packages.get(i);
+ spkg.append(", "+pkg);
+ }
+
+
+ props.put(Constants.FRAMEWORK_SYSTEMPACKAGES, spkg.toString());
+
+ framework.start(props,null);
+ }
+ public void blockingStart() throws Exception{
+ this.start();
+ int to=0;
+ while(framework.getStatus()!=Felix.RUNNING_STATUS) {
+ Thread.sleep(10);
+ to++;
+ if(to>100) throw new Exception("timeout");
+ }
+
+ }
+ public void shutdown(){
+ framework.shutdown();
+ clearCache(cacheDir);
+ }
+
+ private void clearCache(File cacheDir) {
+ if(!isCache(cacheDir)){
+ System.out.println("not valid cache");
+ return;
+ }
+ File[] files=cacheDir.listFiles();
+ for(int i=0; i<files.length; i++){
+ recursiveDelete(files[i]);
+ }
+ }
+ private void recursiveDelete(File file){
+ if(file.isDirectory()){
+ File[] files=file.listFiles();
+ for(int i=0; i<files.length; i++){
+ File f=files[i];
+ recursiveDelete(f);
+ }
+ }
+ file.delete();
+ }
+ private boolean isCache(File cacheDir){
+ if(!cacheDir.exists()||!cacheDir.isDirectory()) return false;
+ else{
+ String[] names=cacheDir.list();
+ for(int i=0;i<names.length;i++){
+ String name=names[i];
+ if(!name.startsWith("bundle")) return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws Exception{
+ FelixLauncher launcher=new FelixLauncher();
+ String jmood="file:../org.apache.felix.jmood_trunk/target/org.apache.felix.jmood-0.8.0-SNAPSHOT.jar";
+ String jmxintrospector="file:../org.apache.felix.mishell/target/org.apache.felix.mishell-0.8.0-SNAPSHOT.jar";
+ launcher.addBundle(jmood);
+ launcher.addBundle(jmxintrospector);
+ launcher.addPackage("org.osgi.framework");
+ launcher.addPackage("org.osgi.util.tracker");
+ launcher.addPackage("org.osgi.service.log");
+ launcher.addPackage("org.osgi.service.packageadmin");
+ launcher.addPackage("org.osgi.service.startlevel");
+ launcher.addPackage("org.osgi.service.permissionadmin");
+ launcher.addPackage("org.osgi.service.useradmin");
+ launcher.addPackage("org.osgi.service.cm");
+ launcher.addPackage("javax.management");
+ launcher.addPackage("javax.management.remote");
+ launcher.addPackage("javax.management.openmbean");
+ launcher.addPackage("javax.script");
+ launcher.start();
+ }
+ public Felix getFramework() {
+ return framework;
+ }
+}
diff --git a/mishell/src/test/java/org/apache/felix/mishell/TypeTest.java b/mishell/src/test/java/org/apache/felix/mishell/TypeTest.java
new file mode 100644
index 0000000..8e34067
--- /dev/null
+++ b/mishell/src/test/java/org/apache/felix/mishell/TypeTest.java
@@ -0,0 +1,19 @@
+package org.apache.felix.mishell;
+
+import org.objectweb.asm.Type;
+
+public class TypeTest {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ StringBuffer s=new StringBuffer();
+ s.append("bolean type: ");
+ s.append(Type.BOOLEAN_TYPE.getDescriptor()+"\n");
+ s.append("String: "+Type.getType((new String()).getClass()));
+ System.out.println(s);
+
+ }
+
+}