Adding an MBean and its associated graphical tab for interacting with
obr on a remote location.

- obrprobe : is the mbean representing obr
- obrprobe.tab : is the tab that is automatically integrated in the
  jmxconsole

to test :
- go into mosgi.doc
- start 2 terminal
- run ./core.sh on terminal 1
- run ./jmxconsole.sh on terminal 2
- click on the left tree to deploy it
- click on the 127.0.0.1 gateway



git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@438475 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/mosgi.doc/config.properties.core b/mosgi.doc/config.properties.core
index c7cc576..67f30dc 100644
--- a/mosgi.doc/config.properties.core
+++ b/mosgi.doc/config.properties.core
@@ -22,13 +22,16 @@
  file:../mosgi.jmx.rmiconnector/target/org.apache.felix.mosgi.jmx.rmiconnector-0.8.0-SNAPSHOT.jar \
  file:../mosgi.console.ifc/target/org.apache.felix.mosgi.console.ifc-0.8.0-SNAPSHOT.jar \
  file:../mosgi.managedelements.osgiprobes/target/org.apache.felix.mosgi.managedelements.osgiprobes-0.8.0-SNAPSHOT.jar \
- file:../mosgi.managedelements.bundlesprobes/target/org.apache.felix.mosgi.managedelements.bundlesprobes-0.8.0-SNAPSHOT.jar
+ file:../mosgi.managedelements.bundlesprobes/target/org.apache.felix.mosgi.managedelements.bundlesprobes-0.8.0-SNAPSHOT.jar \
+ file:../mosgi.managedelements.obrprobe/target/org.apache.felix.mosgi.managedelements.obrprobe-0.8.0-SNAPSHOT.jar
  
 # if we need the http jmx connector
 # file:../mosgi.jmx.httpconnector/target/org.apache.felix.mosgi.jmx.httpconnector-0.8.0-SNAPSHOT.jar
 
 
 insa.jmxconsole.tab.url.osgiprobestab=file:../mosgi.managedelements.osgiprobes.tab/target/org.apache.felix.mosgi.managedelements.osgiprobes.tab-0.8.0-SNAPSHOT.jar
+insa.jmxconsole.tab.url.bundlesprobestab=file:../mosgi.managedelements.bundlesprobes.tab/target/org.apache.felix.mosgi.managedelements.bundlesprobes.tab-0.8.0-SNAPSHOT.jar
+insa.jmxconsole.tab.url.obrprobetab=file:../mosgi.managedelements.obrprobe.tab/target/org.apache.felix.mosgi.managedelements.obrprobe.tab-0.8.0-SNAPSHOT.jar
 
 #insa.jmxconsole.rmiport.t1=1100
 
@@ -340,10 +343,3 @@
  org.xml.sax.ext; \
  org.xml.sax.helpers; \
  version="1.5.0"
-
-insa.jmxconsole.tab.url.osgiprobestab=file:../mosgi.managedelements.osgiprobes.tab/target/org.apache.felix.mosgi.managedelements.osgiprobes.tab-0.8.0-SNAPSHOT.jar
-insa.jmxconsole.tab.url.bundlesprobestab=file:../mosgi.managedelements.bundlesprobes.tab/target/org.apache.felix.mosgi.managedelements.bundlesprobes.tab-0.8.0-SNAPSHOT.jar
-
-insa.jmxconsole.ip1=127.0.0.1
-insa.jmxconsole.profile1=core
-
diff --git a/mosgi.managedelements.obrprobe.tab/pom.xml b/mosgi.managedelements.obrprobe.tab/pom.xml
new file mode 100644
index 0000000..eedbcac
--- /dev/null
+++ b/mosgi.managedelements.obrprobe.tab/pom.xml
@@ -0,0 +1,69 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <name>MOSGi obr remote manipulation tab for the JMX console</name>
+  <artifactId>org.apache.felix.mosgi.managedelements.obrprobe.tab</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.mosgi.console.ifc</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.bundlerepository</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <version>${pom.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>MOSGi obr remote manipulation tab for the JMX console</bundleName>
+            <bundleDescription>MOSGi obr remote manipulation tab for the JMX console</bundleDescription>
+            <bundleActivator>auto-detect</bundleActivator>
+            <bundleDocUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/</bundleDocUrl>
+            <bundleUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar</bundleUrl>
+            <bundleSource>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar</bundleSource>
+            <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+            <exportPackage>
+               ${pom.artifactId}
+            </exportPackage>
+              <importPackage>
+                javax.management,
+                org.osgi.framework,
+                javax.swing,
+                javax.swing.table,
+                org.osgi.service.obr,
+                org.apache.felix.mosgi.console.ifc
+              </importPackage>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/mosgi.managedelements.obrprobe.tab/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/tab/ObrProbeTabUI.java b/mosgi.managedelements.obrprobe.tab/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/tab/ObrProbeTabUI.java
new file mode 100644
index 0000000..f561a8c
--- /dev/null
+++ b/mosgi.managedelements.obrprobe.tab/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/tab/ObrProbeTabUI.java
@@ -0,0 +1,407 @@
+/*
+ *   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.
+ *
+ */
+package org.apache.felix.mosgi.managedelements.obrprobe.tab;
+
+import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.util.ArrayList;
+import java.util.Vector;
+import java.util.StringTokenizer;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.table.AbstractTableModel;
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import java.io.PrintStream;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.InvalidSyntaxException;
+
+//import org.apache.felix.bundlerepository.BundleRepository;
+//import org.apache.felix.bundlerepository.BundleRecord;
+import org.osgi.service.obr.RepositoryAdmin;
+import org.osgi.service.obr.Repository;
+import org.osgi.service.obr.Resource;
+
+
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.SimpleType;
+
+import org.apache.felix.mosgi.console.ifc.Plugin;
+
+public class ObrProbeTabUI extends JPanel implements Plugin, BundleActivator {
+  private static final String OSGI_ON="TabUI:name=ObrProbe";
+
+  private MBeanServerConnection mbsc=null;
+
+  private BundleContext m_context = null;
+  private ServiceReference m_brsRef = null;
+  private RepositoryAdmin m_brs = null;
+
+  private JTextField m_urlField = null;
+  private JButton m_refreshButton = null;
+  private JTable m_bundleTable = null;
+  private JButton m_startAllButton = null;
+  private JButton m_infoButton = null;
+
+  private ObjectName osgiON=null;
+
+  private PrintStream m_out=System.out;
+  private ServiceRegistration sreg=null;
+
+  ///////////////////////////////////////////
+  //           BundleActivator             //
+  ///////////////////////////////////////////
+  public void start(BundleContext context) throws BundleException {
+    m_context = context;
+    try {
+      this.init();
+    }catch(Exception e){
+      e.printStackTrace();
+      throw new BundleException("ObrTabUIException "+e.getMessage());
+    }
+    this.registerServicePlugin();
+  }
+
+  public void stop(BundleContext context) {
+  }
+
+  
+
+  ///////////////////////////////////////////
+  //           Plugin                      //
+  //////////////////////////////////////////
+  public void registerServicePlugin(){
+    sreg = m_context.registerService(Plugin.class.getName(), this, null);
+  }
+  
+  public void unregisterServicePlugin(){
+    sreg.unregister();   
+  }
+  
+  public String pluginLocation(){
+    return m_context.getBundle().getLocation();
+  }
+  
+  public String getName(){return "Remote OBR";}
+
+  public Component getGUI(){return this;}
+
+  public void propertyChange(PropertyChangeEvent e){
+   if (e.getPropertyName().equals(Plugin.NEW_NODE_CONNECTION)){
+     this.mbsc=(MBeanServerConnection)e.getNewValue();
+   }else if(e.getPropertyName().equals(Plugin.EMPTY_NODE)){
+     this.mbsc=null;
+   }
+  }
+
+  /////////////////////
+  // Plugin elements //
+  /////////////////////
+  private void init() throws Exception {
+    this.osgiON=new ObjectName(OSGI_ON);
+    ServiceListener sl = new ServiceListener() {
+      public void serviceChanged(ServiceEvent event) {
+        synchronized (ObrProbeTabUI.this) {
+          // Ignore additional services if we already have one.
+          if ((event.getType() == ServiceEvent.REGISTERED)
+              && (m_brsRef != null)) {
+            return;
+          }
+          // Initialize the service if we don't have one.
+          else if ((event.getType() == ServiceEvent.REGISTERED)
+            && (m_brsRef == null)) {
+            initializeService();
+          }
+          // Unget the service if it is unregistering.
+          else if ((event.getType() == ServiceEvent.UNREGISTERING)
+            && event.getServiceReference().equals(m_brsRef)) {
+            m_context.ungetService(m_brsRef);
+            m_brsRef = null;
+            m_brs = null;
+            // Try to get another service.
+            initializeService();
+          }
+        }
+      }
+    };
+    try {
+      m_context.addServiceListener(sl, "(objectClass=" + RepositoryAdmin.class.getName() + ")");
+    } catch (InvalidSyntaxException ex) {
+      System.err.println("OBRPlugin: " + ex);
+    }
+
+    // Create the gui.
+    createUserInterface();
+
+    // Now try to manually initialize the shell service
+    // since one might already be available.
+    initializeService();
+  }
+
+  private synchronized void initializeService() {
+    if (m_brs != null) {
+      return;
+    }
+    m_brsRef = m_context.getServiceReference(RepositoryAdmin.class.getName());
+    if (m_brsRef == null) {
+      m_urlField.setText("");
+    } else {
+      m_brs = (RepositoryAdmin) m_context.getService(m_brsRef);
+      m_urlField.setText(convertArrayToString(m_brs.listRepositories()));
+    }
+    // Update the table.
+    ((SimpleTableModel) m_bundleTable.getModel()).update();
+  }
+
+  private void createUserInterface() {
+    setLayout(new BorderLayout());
+    add(createBRUrlPanel(), BorderLayout.NORTH);
+    add(createTable(), BorderLayout.CENTER);
+    add(createButtonPanel(), BorderLayout.SOUTH);
+    createEventListeners();
+  }
+
+  private JPanel createBRUrlPanel(){
+    JPanel panel=new JPanel(new FlowLayout());
+    panel.add(new JLabel("URL(s)"));
+    panel.add(m_urlField = new JTextField(20));
+    panel.add(m_refreshButton = new JButton("Refresh"));
+    m_refreshButton.setMnemonic('I');
+    return panel;
+  }
+
+  private JScrollPane createTable() {
+    JScrollPane scroll = new JScrollPane(m_bundleTable = new JTable());
+    scroll.setPreferredSize(new Dimension(100, 100));
+    m_bundleTable.setMinimumSize(new Dimension(0, 0));
+    m_bundleTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+    m_bundleTable.setModel(new SimpleTableModel());
+    m_bundleTable.getColumnModel().getColumn(0).setPreferredWidth(75);
+    m_bundleTable.getColumnModel().getColumn(1).setPreferredWidth(75);
+    m_bundleTable.getColumnModel().getColumn(2).setPreferredWidth(200);
+    return scroll;
+  }
+
+  private JPanel createButtonPanel() {
+    JPanel panel = new JPanel(new FlowLayout());
+    panel.add(m_startAllButton = new JButton("Start all"));
+    panel.add(m_infoButton = new JButton("Info"));
+    m_startAllButton.setMnemonic('S');
+    m_infoButton.setMnemonic('I');
+    return panel;
+  }
+
+  private void createEventListeners() {
+    // Create action listeners.
+    m_refreshButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent event) {
+    /*
+        synchronized (ObrProbeTabUI.this) {
+          if (m_brs == null) {
+            return;
+          } else if (m_urlField.getText().length() > 0) {
+            m_brs.setRepositoryURLs(convertStringToArray(m_urlField.getText()));
+          } else {
+            m_urlField.setText(convertArrayToString(m_brs.getRepositoryURLs()));
+          }
+          // Update the table.
+          ((SimpleTableModel) m_bundleTable.getModel()).update();
+        }
+    */
+      }
+    });
+
+    m_startAllButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent event) {
+        synchronized (ObrProbeTabUI.this) {
+         if (mbsc == null) {
+System.out.println("coucou");    
+           return;
+         }
+         int[] rows = m_bundleTable.getSelectedRows();
+         for (int i = 0; i < rows.length; i++) {
+       //Object [] tabo=new Object[]{(String) m_brs.getBundleRecord(rows[i]).getAttribute(BundleRecord.BUNDLE_UPDATELOCATION)};
+           try{
+         /*
+             BundleRecord[] m_records=m_brs.getBundleRecords();
+             Object [] tabo=new Object[]{(String) m_records[rows[i]].getAttribute(BundleRecord.BUNDLE_SYMBOLICNAME), parseVersionString((String) m_records[rows[i]].getAttribute(BundleRecord.BUNDLE_VERSION))};
+             String [] tabc=new String[]{String.class.getName(),new ArrayType(1, SimpleType.INTEGER).getTypeName()};
+         */
+             Object [] tabo=new Object[]{(String)m_bundleTable.getValueAt(rows[i], 0), (String)m_bundleTable.getValueAt(rows[i], 1)};
+         String [] tabc=new String[]{String.class.getName(),String.class.getName()};
+System.out.println("====>"+m_bundleTable.getValueAt(rows[i], 0));
+System.out.println("====>"+m_bundleTable.getValueAt(rows[i], 1));
+             mbsc.invoke(osgiON, "deploy", tabo, tabc);
+       }catch(Exception e){
+         e.printStackTrace();
+       }
+         }
+         m_out.println("");
+        }
+      }
+      });
+   
+
+      m_infoButton.addActionListener(new ActionListener() {
+        public void actionPerformed(ActionEvent event) {
+      /*
+          synchronized (ObrProbeTabUI.this) {
+            if (m_brs == null) {
+              return;
+            }
+            int[] rows = m_bundleTable.getSelectedRows();
+            for (int i = 0; i < rows.length; i++) {
+              if (i != 0) {
+                m_out.println("");
+              }
+              BundleRecord br = m_brs.getBundleRecords()[i];
+              br.printAttributes(m_out);
+            }
+            m_out.println("");
+          }
+    */
+        }
+      });
+  }
+
+    private String[] convertStringToArray(String str) {
+      String[] strs = null;
+      StringTokenizer st = new StringTokenizer(str);
+      if (st.countTokens() > 0) {
+        strs = new String[st.countTokens()];
+        for (int i = 0; (strs != null) && (i < strs.length); i++) {
+          strs[i] = st.nextToken();
+        }
+      }
+      return strs;
+    }
+
+    private String convertArrayToString(Repository[] strs) {
+      StringBuffer str = new StringBuffer();
+      for (int i = 0; (strs != null) && (i < strs.length); i++) {
+        // Add space between URLs.
+        if (i != 0) {
+          str = str.append(" ");
+        }
+        str.append(strs[i].getURL());
+      }
+      return str.toString();
+    }
+
+    public static Integer[] parseVersionString(String s) {
+      Integer[] version = new Integer[] { new Integer(0), new Integer(0), new Integer(0) };
+      if (s != null) {
+        StringTokenizer st = new StringTokenizer(s, ".");
+        if (st.hasMoreTokens()) {
+          try {
+            version[0] = new Integer(st.nextToken());
+            if (st.hasMoreTokens()) {
+              version[1] = new Integer(st.nextToken());
+              if (st.hasMoreTokens()) {
+                version[2] = new Integer(st.nextToken());
+              }
+            }
+            return version;
+          } catch (NumberFormatException ex) {
+            throw new IllegalArgumentException( "Improper version number.");
+          }
+        }
+      }
+     return version;
+    }
+
+    private class SimpleTableModel extends AbstractTableModel {
+      public int getRowCount() { 
+        if (m_brs==null){
+          return 0;
+    }else{
+      try {
+        Resource[] resources = m_brs.discoverResources("(|(presentationname=*)(symbolicname=*))");
+            return resources.length;
+      }catch(Exception e){
+        System.out.println("OBR not working, network problem ?");
+        //e.printStackTrace();
+        return 0;
+      }
+    }
+      }
+
+      public int getColumnCount() {
+        return 3;
+      }
+
+      public String getColumnName(int column) {
+        if (column == 0) {
+          return "Name";
+        } else if (column == 1) {
+          return "Version";
+        } else if (column == 2) {
+          return "Description";
+        }    
+        return "";
+      }
+
+      public Class getColumnClass(int column) {
+        return String.class;
+      }
+
+      public boolean isCellEditable(int row, int column) {
+        return false;
+      }
+
+      public Object getValueAt(int row, int column) {
+        Resource br = null;
+        synchronized (ObrProbeTabUI.this) {
+          if (m_brs != null) {
+        br=m_brs.discoverResources("(|(presentationname=*)(symbolicname=*))")[row];
+          }
+        }
+        if (br != null) {
+          if (column == 0) {
+            return br.getPresentationName();
+          } else if (column == 1) {
+            return br.getVersion().toString();
+          } else if (column == 2) {
+            return br.getSymbolicName();
+          }
+        }
+        return null;
+      }
+                
+      public void update() {
+        fireTableDataChanged();
+      }
+    }
+  }
diff --git a/mosgi.managedelements.obrprobe/pom.xml b/mosgi.managedelements.obrprobe/pom.xml
new file mode 100644
index 0000000..2baee27
--- /dev/null
+++ b/mosgi.managedelements.obrprobe/pom.xml
@@ -0,0 +1,75 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <name>MOSGi JMX MBean for obr interaction</name>
+  <artifactId>org.apache.felix.mosgi.managedelements.obrprobe</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.mosgi.console.ifc</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.framework</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.bundlerepository</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <version>${pom.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>MOSGi JMX MBean for obr interaction</bundleName>
+            <bundleDescription>MOSGi JMX MBean for obr interaction</bundleDescription>
+            <bundleActivator>auto-detect</bundleActivator>
+            <bundleDocUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/</bundleDocUrl>
+            <bundleUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar</bundleUrl>
+            <bundleSource>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar</bundleSource>
+            <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+            <exportPackage>
+              ${pom.artifactId};specification-version="1.0.0"
+            </exportPackage>
+            <importPackage>
+              org.osgi.framework;specification-version="1.0.0",
+              org.osgi.service.log;specification-version="1.0.0",
+              javax.management;specification-version="1.0.0",
+              javax.management.openmbean;specification-version="1.0.0",
+              org.osgi.service.obr,
+              org.apache.felix.mosgi.console.ifc;specification-version="1.0.0"
+            </importPackage>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/mosgi.managedelements.obrprobe/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/ObrProbe.java b/mosgi.managedelements.obrprobe/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/ObrProbe.java
new file mode 100644
index 0000000..c940108
--- /dev/null
+++ b/mosgi.managedelements.obrprobe/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/ObrProbe.java
@@ -0,0 +1,235 @@
+/*
+ *   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.
+ *
+ */
+package org.apache.felix.mosgi.managedelements.obrprobe;
+
+/**
+ * TODO : Should listen to Agent Service lifecycle
+ *        Need to change ObjectName
+ *        Should listen to serviceLifecycle
+**/
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.AttributeChangeNotification;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+
+//import org.apache.felix.bundlerepository.BundleRepository;
+import org.osgi.service.obr.RepositoryAdmin;
+import org.osgi.service.obr.Resolver;
+import org.osgi.service.obr.Resource;
+import org.osgi.framework.Version;
+
+import org.osgi.service.log.LogService;
+
+public class ObrProbe implements BundleActivator, ObrProbeMBean {
+
+  private String version = null;
+  private static String tabNameString = "TabUI:name=ObrProbe";
+
+  private ObjectName tabName = null;
+  private MBeanServer server = null;
+  private BundleContext bc = null;
+  private ServiceReference sr = null;
+
+
+  ////////////////////////////////////////////////////////
+  //     TabIfc (from ObrProbeMBean)                  //
+  ////////////////////////////////////////////////////////
+  public String getBundleName() {
+    return this.bc.getProperty("insa.jmxconsole.tab.url.obrprobetab");
+  }
+
+
+  ////////////////////////////////////////////////////////
+  //       BundleActivator                              //
+  ////////////////////////////////////////////////////////
+  public void start(BundleContext context) throws Exception  {
+    this.bc=context;
+    this.version=(String)bc.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);
+    this.log(LogService.LOG_INFO, "Starting obrProbe MBean " + this.version,null);
+    this.tabName=new ObjectName(tabNameString);
+    this.sr = context.getServiceReference(MBeanServer.class.getName());
+    if (sr!=null){
+      this.connectToAgent(sr);
+    }
+    this.log(LogService.LOG_INFO, "ObrProbe MBean "+this.version+" started", null);
+  }
+
+
+  public void stop(BundleContext context) {
+    this.log(LogService.LOG_INFO, "Stopping obrprobe MBean "+this.version, null);
+    if (this.server!=null){
+      this.disconnectFromAgent();
+    }
+    this.sr=null;
+    this.log(LogService.LOG_INFO, "obrProbe MBean "+this.version+" stopped", null);
+    this.bc=null;
+  }
+
+  ////////////////////////////////////////////////////////
+  //       ObrProbeMBean                              //
+  ////////////////////////////////////////////////////////
+  public void deploy(String location,String version){
+    ServiceReference sr=this.bc.getServiceReference(RepositoryAdmin.class.getName());
+
+    System.out.println("Starting "+location+" "+version);
+    if (sr!=null){
+      RepositoryAdmin brs=(RepositoryAdmin)this.bc.getService(sr);
+      Resolver resolver=brs.resolver();
+      Resource ressource = selectNewestVersion(searchRepository(brs, location, version));
+      if (ressource!=null){
+	resolver.add(ressource);
+      }
+      if ((resolver.getAddedResources() != null) &&
+            (resolver.getAddedResources().length > 0)) {
+        if (resolver.resolve()) {
+          try{
+            resolver.deploy(true); //Bundles are started
+          }catch (IllegalStateException ex) {
+            System.out.println(ex);
+          }
+        }
+      }
+    }else{
+      this.log(LogService.LOG_ERROR, "No BundleRepository Service", null);
+    }
+  }
+
+  ////////////////////////////////////////////////////////
+  //       ServiceListener                              //
+  ////////////////////////////////////////////////////////
+  public void serviceChanged(ServiceEvent event) {
+    ServiceReference sr=event.getServiceReference();
+    Object service=bc.getService(sr);
+    if (this.server==null && event.getType()==ServiceEvent.REGISTERED && service instanceof MBeanServer){
+      this.connectToAgent(sr);
+    }
+    if (this.server!=null){
+      if(event.getType()==ServiceEvent.UNREGISTERING && service instanceof MBeanServer){
+        this.disconnectFromAgent();
+      }
+    }
+  }
+
+  private void connectToAgent(ServiceReference sr){
+    this.log(LogService.LOG_INFO, "Registering to agent", null);
+    try{
+      this.server=(MBeanServer)this.bc.getService(sr);
+      this.server.registerMBean(this, tabName);
+    }catch (Exception e){
+      e.printStackTrace();
+    }
+    this.log(LogService.LOG_INFO, "Registered to agent", null);
+  }
+  
+  private void disconnectFromAgent(){
+    this.log(LogService.LOG_INFO, "Unregistering from agent", null);
+    try {
+      server.unregisterMBean(tabName);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    this.server=null;
+    this.bc.ungetService(this.sr);
+    this.log(LogService.LOG_INFO, "Unregistered from agent", null);
+  }
+
+  private void log(int prio, String message, Throwable t){
+    if (this.bc!=null){
+      ServiceReference logSR=this.bc.getServiceReference(LogService.class.getName());
+      if (logSR!=null){
+        ((LogService)this.bc.getService(logSR)).log(prio, message, t);
+      }else{
+        System.out.println("No Log Service");
+      }
+    }else{
+      System.out.println(this.getClass().getName()+".log: No bundleContext");
+    }
+  }
+
+  private Resource[] searchRepository(RepositoryAdmin brs, String targetId, String targetVersion)
+  {
+        // Try to see if the targetId is a bundle ID.
+        try
+        {
+            Bundle bundle = bc.getBundle(Long.parseLong(targetId));
+            targetId = bundle.getSymbolicName();
+        }
+        catch (NumberFormatException ex)
+        {
+            // It was not a number, so ignore.
+        }
+
+        // The targetId may be a bundle name or a bundle symbolic name,
+        // so create the appropriate LDAP query.
+        StringBuffer sb = new StringBuffer("(|(presentationname=");
+        sb.append(targetId);
+        sb.append(")(symbolicname=");
+        sb.append(targetId);
+        sb.append("))");
+        if (targetVersion != null)
+        {
+            sb.insert(0, "(&");
+            sb.append("(version=");
+            sb.append(targetVersion);
+            sb.append("))");
+        }
+        return brs.discoverResources(sb.toString());
+    }
+
+    private Resource selectNewestVersion(Resource[] resources)
+    {
+        int idx = -1;
+        Version v = null;
+        for (int i = 0; (resources != null) && (i < resources.length); i++)
+        {
+            if (i == 0)
+            {
+                idx = 0;
+                v = resources[i].getVersion();
+            }
+            else
+            {
+                Version vtmp = resources[i].getVersion();
+                if (vtmp.compareTo(v) > 0)
+                {
+                    idx = i;
+                    v = vtmp;
+                }
+            }
+        }
+
+        return (idx < 0) ? null : resources[idx];
+    }
+
+
+}
diff --git a/mosgi.managedelements.obrprobe/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/ObrProbeMBean.java b/mosgi.managedelements.obrprobe/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/ObrProbeMBean.java
new file mode 100644
index 0000000..69e6782
--- /dev/null
+++ b/mosgi.managedelements.obrprobe/src/main/java/org/apache/felix/mosgi/managedelements/obrprobe/ObrProbeMBean.java
@@ -0,0 +1,29 @@
+/*
+ *   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.
+ *
+ */
+package org.apache.felix.mosgi.managedelements.obrprobe;
+
+/**
+ * Comments : It impossible to load a standard MBean, since introspection
+ *            does not rely on a classloader
+**/
+
+import java.util.Vector;
+import org.apache.felix.mosgi.console.ifc.TabIfc;
+
+public interface ObrProbeMBean extends TabIfc {
+  public void deploy(String location, String version);
+}
diff --git a/pom.xml b/pom.xml
index c584d3a..a27c890 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,6 +103,8 @@
         <module>mosgi.managedelements.osgiprobes.tab</module>
         <module>mosgi.managedelements.bundlesprobes</module>
         <module>mosgi.managedelements.bundlesprobes.tab</module>
+        <module>mosgi.managedelements.obrprobe</module>
+        <module>mosgi.managedelements.obrprobe.tab</module>
 
         <module>ipojo.plugin</module>
         <module>ipojo.arch</module>