You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by rw...@apache.org on 2011/02/22 15:53:20 UTC

svn commit: r1073353 - in /geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main: java/org/apache/geronimo/console/javabean/ java/org/apache/geronimo/console/json/ java/org/apache/geronimo/console/portlet/ webapp/WEB-INF/view/

Author: rwonly
Date: Tue Feb 22 14:53:19 2011
New Revision: 1073353

URL: http://svn.apache.org/viewvc?rev=1073353&view=rev
Log:
GERONIMO-5774 osgi portlet improvements (improve performance and add view wired bundles utility)

Added:
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/BundleGridJSONObject.java   (with props)
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestGridJSONObject.java   (with props)
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestHeaderJSONObject.java   (with props)
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairGridJSONObject.java   (with props)
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairJSONObject.java   (with props)
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/WiredBundlesJSONObject.java   (with props)
Removed:
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/BundleHeaderJSONObject.java
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/GridJSONObject.java
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/HeadersJSONObject.java
Modified:
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/javabean/OSGiBundle.java
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/portlet/BundlesPortlet.java
    geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/webapp/WEB-INF/view/BundlesView.jsp

Modified: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/javabean/OSGiBundle.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/javabean/OSGiBundle.java?rev=1073353&r1=1073352&r2=1073353&view=diff
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/javabean/OSGiBundle.java (original)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/javabean/OSGiBundle.java Tue Feb 22 14:53:19 2011
@@ -38,7 +38,7 @@ public class OSGiBundle {
     
     public OSGiBundle(Bundle bundle) {
 		this(bundle.getBundleId(),
-		        bundle.getSymbolicName(),
+		        bundle.getSymbolicName()==null?bundle.getLocation():bundle.getSymbolicName(),
 		        bundle.getVersion().toString(),
 		        bundle.getState()
 		        

Added: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/BundleGridJSONObject.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/BundleGridJSONObject.java?rev=1073353&view=auto
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/BundleGridJSONObject.java (added)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/BundleGridJSONObject.java Tue Feb 22 14:53:19 2011
@@ -0,0 +1,38 @@
+/**
+ * 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.geronimo.console.json;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.geronimo.console.javabean.OSGiBundle;
+import org.json.JSONException;
+import org.json.JSONObject;
+public class BundleGridJSONObject extends JSONObject{
+    
+	public BundleGridJSONObject(List<OSGiBundle> bundles) throws JSONException{
+		this.put("identifier", "id");
+		this.put("label", "description");
+		
+		List<BundleJSONObject> items=new LinkedList<BundleJSONObject>();
+		for(OSGiBundle bundle:bundles){			
+			items.add(new BundleJSONObject(bundle));
+		}
+		this.put("items", items);
+	}
+	
+}

Propchange: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/BundleGridJSONObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestGridJSONObject.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestGridJSONObject.java?rev=1073353&view=auto
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestGridJSONObject.java (added)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestGridJSONObject.java Tue Feb 22 14:53:19 2011
@@ -0,0 +1,122 @@
+/**
+ * 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.geronimo.console.json;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+// FIXME should replaced by import org.apache.aries.util.ManifestHeaderUtils; in next release
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+
+
+public class ManifestGridJSONObject extends JSONObject{
+    
+    public ManifestGridJSONObject(Dictionary<String,String> headers) throws JSONException{
+        this.put("identifier", "hkey");
+        this.put("label", "description");
+        
+        List<ManifestHeaderJSONObject> items=new LinkedList<ManifestHeaderJSONObject>();
+        
+        Enumeration<String> keys = headers.keys();
+        while(keys.hasMoreElements()){
+            String key = (String)keys.nextElement();
+            
+            if (key.equals("Import-Package")||key.equals("Export-Package")||key.equals("Ignore-Package")||key.equals("Private-Package")){
+                items.add(new ManifestHeaderJSONObject(key, formatPackageHeader((String)headers.get(key))));
+            } else {
+                items.add(new ManifestHeaderJSONObject(key, (String)headers.get(key)));
+            }
+        }
+        
+        this.put("items", items);
+    }
+
+    
+    private String formatPackageHeader(String header){
+        List<String> packagesList = ManifestHeaderProcessor.split(header, ",");
+        Collections.sort(packagesList);
+
+        String result = "";
+        for (Iterator<String> it = packagesList.iterator(); it.hasNext(); result+=formatPackageValue(it.next())+"<BR/>");
+        
+        return result;
+    }
+    
+    /*
+     * Format a package value from
+     * org.apache.aries.util.tracker;uses:="org.osgi.util.tracker,org.osgi.framework,org.osgi.framework.launch";version="0.2.0.incubating",
+     * to
+     * org.apache.aries.util.tracker;version="0.2.0.incubating",
+     *     uses:="org.osgi.util.tracker,
+     *         org.osgi.framework,
+     *         org.osgi.framework.launch",
+     */
+    
+    private String formatPackageValue(String pkg) {
+        String result = "";
+        
+        String[] parts = pkg.split(";");
+        
+        if (parts!=null && parts.length>0) { //it should at least have a package name;
+            result = parts[0]; 
+        }
+        
+        String uses = "";
+        for (int i=1; i<parts.length;i++){
+            String aPart = parts[i];
+            if (aPart.indexOf("uses:=")!=-1){  //deal with the "uses:=.." specially, because it always very long..
+                uses+=";<BR/>&nbsp;&nbsp;&nbsp;&nbsp;"+"uses:="+"\"";
+                
+                String usesValue = "";
+                if (aPart.indexOf("\"")!=-1){
+                    usesValue = aPart.substring(aPart.indexOf("\"")+1, aPart.lastIndexOf("\""));
+                } else {  // for such using uses:=javassist;
+                    usesValue = aPart.substring(aPart.indexOf(":=")+2);
+                }
+                
+                List<String> usesValueList = ManifestHeaderProcessor.split(usesValue,",");
+                Collections.sort(usesValueList);
+                Iterator<String> usesIT = usesValueList.iterator();
+                if (usesIT.hasNext()){ //it should at least have a value;
+                    uses += usesIT.next();
+                }
+                while (usesIT.hasNext()){
+                    uses += ",<BR/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+usesIT.next();
+                }
+                
+                uses+="\"";
+                
+            } else {  //maybe "version=..", maybe "resolution=.."
+                result += ";"+aPart;
+            }
+        }
+        
+        if (uses!="") result += uses;
+        
+        return result+",";
+    }
+    
+    
+}

Propchange: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestGridJSONObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestHeaderJSONObject.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestHeaderJSONObject.java?rev=1073353&view=auto
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestHeaderJSONObject.java (added)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestHeaderJSONObject.java Tue Feb 22 14:53:19 2011
@@ -0,0 +1,28 @@
+/**
+ * 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.geronimo.console.json;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class ManifestHeaderJSONObject extends JSONObject{
+    public ManifestHeaderJSONObject(String key, String value) throws JSONException{
+        this.put("hkey", key);
+        this.put("hvalue", value);
+    }
+}

Propchange: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/ManifestHeaderJSONObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairGridJSONObject.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairGridJSONObject.java?rev=1073353&view=auto
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairGridJSONObject.java (added)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairGridJSONObject.java Tue Feb 22 14:53:19 2011
@@ -0,0 +1,18 @@
+package org.apache.geronimo.console.json;
+
+import java.util.List;
+import java.util.Set;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+
+
+public class PackageBundlePairGridJSONObject extends JSONObject{
+    public PackageBundlePairGridJSONObject(Set<PackageBundlePairJSONObject> items) throws JSONException{
+        this.put("identifier", "fid");
+        this.put("label", "description");
+        
+        this.put("items", items);
+    }
+}

Propchange: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairGridJSONObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairJSONObject.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairJSONObject.java?rev=1073353&view=auto
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairJSONObject.java (added)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairJSONObject.java Tue Feb 22 14:53:19 2011
@@ -0,0 +1,53 @@
+package org.apache.geronimo.console.json;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+
+public class PackageBundlePairJSONObject extends JSONObject {
+    
+    String pname;
+    String bname;
+    
+    public PackageBundlePairJSONObject(int fakeId, String packageName, String bundleName) throws JSONException{
+        this.put("fid", fakeId); //use as the identifier in datagrid's store
+        
+        this.put("pname", packageName);
+        this.put("bname", bundleName);
+        
+        pname=packageName;
+        bname=bundleName;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final PackageBundlePairJSONObject other = (PackageBundlePairJSONObject) obj;
+        if (this.pname != other.pname && (this.pname == null || !this.pname.equals(other.pname))) {
+            return false;
+        }
+        if (this.bname != other.bname && (this.bname == null || !this.bname.equals(other.bname))) {
+            return false;
+        }
+
+        return true;
+        
+    }
+    
+    @Override
+    public int hashCode() {
+        int hash = 11;
+        hash = 17 * hash + (pname != null ? pname.hashCode():0);
+        hash = 17 * hash + (bname != null ? bname.hashCode():0);
+
+        return hash;
+    }
+    
+}

Propchange: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/PackageBundlePairJSONObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/WiredBundlesJSONObject.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/WiredBundlesJSONObject.java?rev=1073353&view=auto
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/WiredBundlesJSONObject.java (added)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/WiredBundlesJSONObject.java Tue Feb 22 14:53:19 2011
@@ -0,0 +1,12 @@
+package org.apache.geronimo.console.json;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class WiredBundlesJSONObject extends JSONObject{
+    public WiredBundlesJSONObject(PackageBundlePairGridJSONObject importingPairGrid, PackageBundlePairGridJSONObject exportingPairGrid) throws JSONException{
+        this.put("importingBundles", importingPairGrid);
+        this.put("exportingBundles", exportingPairGrid);
+    }
+    
+}

Propchange: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/json/WiredBundlesJSONObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/portlet/BundlesPortlet.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/portlet/BundlesPortlet.java?rev=1073353&r1=1073352&r2=1073353&view=diff
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/portlet/BundlesPortlet.java (original)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/java/org/apache/geronimo/console/portlet/BundlesPortlet.java Tue Feb 22 14:53:19 2011
@@ -20,9 +20,14 @@ import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
 
 import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
@@ -41,8 +46,14 @@ import org.apache.commons.fileupload.Fil
 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 import org.apache.commons.fileupload.portlet.PortletFileUpload;
 import org.apache.geronimo.console.javabean.OSGiBundle;
-import org.apache.geronimo.console.json.GridJSONObject;
-import org.apache.geronimo.console.json.HeadersJSONObject;
+import org.apache.geronimo.console.json.BundleGridJSONObject;
+import org.apache.geronimo.console.json.ManifestGridJSONObject;
+import org.apache.geronimo.console.json.PackageBundlePairGridJSONObject;
+import org.apache.geronimo.console.json.PackageBundlePairJSONObject;
+import org.apache.geronimo.console.json.WiredBundlesJSONObject;
+import org.apache.xbean.osgi.bundle.util.BundleDescription;
+import org.apache.xbean.osgi.bundle.util.BundleUtils;
+import org.apache.xbean.osgi.bundle.util.BundleDescription.ExportPackage;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -50,6 +61,8 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
 import org.osgi.service.startlevel.StartLevel;
 
 public class BundlesPortlet extends GenericPortlet {
@@ -62,20 +75,36 @@ public class BundlesPortlet extends Gene
     private PortletRequestDispatcher helpView;
 
     
+    BundleContext bundleContext = null;
+    StartLevel startLevelService = null;
+    
     public void init(PortletConfig portletConfig) throws PortletException {
         super.init(portletConfig);
         normalView = portletConfig.getPortletContext().getRequestDispatcher(NORMALVIEW_JSP);
         maximizedView = portletConfig.getPortletContext().getRequestDispatcher(MAXIMIZEDVIEW_JSP);
         helpView = portletConfig.getPortletContext().getRequestDispatcher(HELPVIEW_JSP);
     }
-
+    
     public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException,
-            IOException {
+    IOException {
         // this portlet use dojo/ajax to process action. so all the actions are in serverResource method.
     }
-
+    
+    protected void doHelp(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException,
+    IOException {
+        helpView.include(renderRequest, renderResponse);
+    }
+    
     protected void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException,
             PortletException {
+
+        //get bundleContext
+        bundleContext = (BundleContext) renderRequest.getPortletSession().getPortletContext().getAttribute("osgi-bundlecontext");
+        
+        //get the StartLeval object
+        ServiceReference startLevelRef = bundleContext.getServiceReference(StartLevel.class.getCanonicalName());
+        startLevelService = (StartLevel) bundleContext.getService(startLevelRef);
+        
         if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) {
             return;
         } else if (WindowState.NORMAL.equals(renderRequest.getWindowState())) {
@@ -91,40 +120,106 @@ public class BundlesPortlet extends Gene
         }
     }
 
-    protected void doHelp(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException,
-            IOException {
-        helpView.include(renderRequest, renderResponse);
-    }
 
-    private void doBundlesView(RenderRequest request, RenderResponse response) {
 
-        BundleContext bundleContext = (BundleContext) request.getPortletSession().getPortletContext().getAttribute(
-                "osgi-bundlecontext");
+    private void doBundlesView(RenderRequest request, RenderResponse response) {
 
         Bundle[] bundles = bundleContext.getBundles();
 
         // list contains bundles converted from Bundle objects
         ArrayList<OSGiBundle> OSGiBundleList = new ArrayList<OSGiBundle>();
 
+        
         // convert Bundle to OSGiBundle
         for (Bundle bundle : bundles) {
-            OSGiBundle osgiBundle = new OSGiBundle(bundle);
-            OSGiBundleList.add(osgiBundle);
+            if (!checkSysBundle(bundle)){
+                OSGiBundle osgiBundle = new OSGiBundle(bundle);
+                OSGiBundleList.add(osgiBundle);
+            }
         }
-
+        
         try {
-            JSONObject grid = new GridJSONObject(OSGiBundleList);
+            JSONObject grid = new BundleGridJSONObject(OSGiBundleList);
             request.setAttribute("GridJSONObject", grid);
         } catch (JSONException e) {
             e.printStackTrace();
         }
 
     }
+    
+    private boolean checkSysBundle(Bundle bundle){
+        
+        // check start level
+        if (startLevelService!=null && startLevelService.getBundleStartLevel(bundle) <= 50){ //config.properties set karaf.systemBundlesStartLevel=50
+            return true;
+        }
+        
+        // check symbolic name
+        String symbolicName = bundle.getSymbolicName();
+        if (symbolicName!=null){
+            if (symbolicName.indexOf("sample") != -1 
+                || symbolicName.indexOf("demo") != -1 
+                || symbolicName.indexOf("test") != -1 
+                || symbolicName.indexOf("example") != -1 
+                ){
+                return false;
+            }
+                
+            if (symbolicName.indexOf("org.apache.geronimo.modules") != -1
+                || symbolicName.indexOf("org.apache.geronimo.configs") != -1
+                || symbolicName.indexOf("org.apache.geronimo.specs") != -1
+                || symbolicName.indexOf("org.apache.geronimo.bundles") != -1
+                || symbolicName.indexOf("org.apache.geronimo.ext") != -1
+                || symbolicName.indexOf("org.apache.geronimo.plugins") != -1
+                || symbolicName.indexOf("org.apache.geronimo.framework") != -1
+                || symbolicName.indexOf("org.apache.geronimo.javamail") != -1
+                || symbolicName.indexOf("org.apache.geronimo.components") != -1
+                || symbolicName.indexOf("org.apache.xbean") != -1
+                || symbolicName.indexOf("org.apache.portals") != -1
+                || symbolicName.indexOf("org.apache.yoko") != -1
+                || symbolicName.indexOf("org.apache.openejb") != -1
+                || symbolicName.indexOf("org.apache.openjpa") != -1
+                || symbolicName.indexOf("org.apache.bval") != -1
+                || symbolicName.indexOf("org.apache.myfaces") != -1
+                || symbolicName.indexOf("openwebbeans") != -1
+                || symbolicName.indexOf("org.apache.aries") != -1
+                || symbolicName.indexOf("org.tranql") != -1
+                || symbolicName.indexOf("org.apache.commons") != -1
+                ){
+                return true;
+            }
+        }
+        
+        return false;
+        
+        
+    }
+    
+    private boolean checkBundleState(BundleContext bundleContext, Long id, int targetState) throws InterruptedException{
+        for (int j = 0; j<5; j++){ // give system 5 times to check the new status
+            if (bundleContext.getBundle(id).getState() == targetState){
+                return true;
+            } else {
+                Thread.sleep(500L);
+            }
+        }
+        return false;
+    }
+    
+    private boolean checkBundleUninstalled(BundleContext bundleContext, Long id) throws InterruptedException{
+        for (int j = 0; j<5; j++){ // give system 5 times to check the new status
+            if (bundleContext.getBundle(id) == null){
+                return true;
+            } else {
+                Thread.sleep(500L);
+            }
+        }
+        return false;
+    }
 
     public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException {
         
-        BundleContext bundleContext = (BundleContext) request.getPortletSession().getPortletContext().getAttribute(
-                "osgi-bundlecontext");
+        bundleContext = (BundleContext) request.getPortletSession().getPortletContext().getAttribute("osgi-bundlecontext");
         
         String resourceId = request.getResourceID();
   
@@ -133,95 +228,60 @@ public class BundlesPortlet extends Gene
             String jsonData = request.getParameter("bundlesActionParam");
             try {
                 /*
-                 * The format of a request json looks like { "action":"start" "items":[ {"id":0} {"id":25} ] }
+                 * The format of a request json looks like { "action":"start", "id":25}
                  */
                 JSONObject jo = new JSONObject(jsonData);
                 String action = jo.getString("action");
-                JSONArray items = jo.getJSONArray("items");
+                Long id = Long.valueOf(jo.getString("id"));
 
                 /*
                  * The format of a response json looks like { "items":[ {"id":0, "state":"Active"} {"id":25, "state":"Resolved"} ] }
                  * PS:  {"id":0, "state":"err"} means the state maybe not change, need user refresh the portlet.
                  */
-                LinkedList<JSONObject> resultItems = new LinkedList<JSONObject>();
+                JSONObject resultItem = new JSONObject();;
                 
                 if (action.equals("start")){
-                    for (int i = 0; i < items.length(); i++) {
-                        Long id = items.getJSONObject(i).getLong("id");
-                        
-                        // start the bundle
-                        bundleContext.getBundle(id).start();
-                        
-                        // prepare response
-                        JSONObject resultItem = new JSONObject();
-                        resultItem.put("id", id);
-                        
-                        resultItem.put("state", "err");
-                        for (int j = 0; j<5; j++){ // give system 5 times to check the new status
-                            if (bundleContext.getBundle(id).getState() == Bundle.ACTIVE){
-                                resultItem.put("state", "Active");
-                                break;
-                            } else {
-                                Thread.sleep(500L);
-                            }
-                        }
-                        
-                        resultItems.add(resultItem);
+                    // start the bundle
+                    bundleContext.getBundle(id).start();
+
+                    // prepare response
+                    resultItem.put("id", id);
+                    resultItem.put("state", "err");
+                    if (checkBundleState(bundleContext, id, Bundle.ACTIVE)) {
+                        resultItem.put("state", OSGiBundle.getStateName(Bundle.ACTIVE));
                     }
+
                 } else if (action.equals("stop")){
-                    for (int i = 0; i < items.length(); i++) {
-                        Long id = items.getJSONObject(i).getLong("id");
-                        
-                        // stop the bundle
-                        bundleContext.getBundle(id).stop();
-                        
-                        // prepare response
-                        JSONObject resultItem = new JSONObject();
-                        resultItem.put("id", id);
-                        
-                        resultItem.put("state", "err");
-                        for (int j = 0; j<5; j++){ // give system 5 times to check the new status
-                            if (bundleContext.getBundle(id).getState() == Bundle.RESOLVED){
-                                resultItem.put("state", "Resolved");
-                                break;
-                            } else {
-                                Thread.sleep(500L);
-                            }
-                        }
-                        
-                        resultItems.add(resultItem);
+                    // stop the bundle
+                    bundleContext.getBundle(id).stop();
+
+                    // prepare response
+                    resultItem.put("id", id);
+                    resultItem.put("state", "err");
+                    if (checkBundleState(bundleContext, id, Bundle.RESOLVED)) {
+                        resultItem.put("state", OSGiBundle.getStateName(Bundle.RESOLVED));
                     }
-                                        
+     
                 } else if (action.equals("uninstall")){
-                    for (int i = 0; i < items.length(); i++) {
-                        Long id = items.getJSONObject(i).getLong("id");
-                        
-                        // uninstall the bundle
-                        bundleContext.getBundle(id).uninstall();
-                        
-                        // prepare response
-                        JSONObject resultItem = new JSONObject();
-                        resultItem.put("id", id);
-                        
-                        resultItem.put("state", "err");
-                        for (int j = 0; j<5; j++){ // give system 5 times to check the new status
-                            if (bundleContext.getBundle(id) == null){
-                                resultItem.put("state", "Uninstalled");
-                                break;
-                            } else {
-                                Thread.sleep(500L);
-                            }
-                        }
-                        
-                        resultItems.add(resultItem);
+                    
+                    // uninstall the bundle
+                    bundleContext.getBundle(id).uninstall();
+
+                    // prepare response
+                    resultItem.put("id", id);
+                    resultItem.put("state", "err");
+                    if (checkBundleUninstalled(bundleContext, id)) {
+                        resultItem.put("state", OSGiBundle.getStateName(Bundle.UNINSTALLED));
                     }
-                }
 
-                JSONObject result = new JSONObject();
-                result.put("items", resultItems);
+                } else if (action.equals("refresh")){
+                    // prepare response
+                    resultItem.put("id", id);
+                    resultItem.put("state", OSGiBundle.getStateName(bundleContext.getBundle(id).getState()));
+                }   
                 
                 PrintWriter writer = response.getWriter();
-                writer.print(result.toString());
+                writer.print(resultItem);
                 
             } catch (JSONException e) {
                 e.printStackTrace();
@@ -230,25 +290,234 @@ public class BundlesPortlet extends Gene
             }catch (InterruptedException e) {
                 e.printStackTrace();
             }
-        } else if (resourceId.equals("showSingleBundle")) {
+            
+            
+        } else if (resourceId.equals("showManifest")) {
             String str_id = request.getParameter("id");
             long id = Long.parseLong(str_id);
 
             try {
                 PrintWriter writer = response.getWriter();
-                writer.print(new HeadersJSONObject(bundleContext.getBundle(id).getHeaders()));
+                writer.print(new ManifestGridJSONObject(bundleContext.getBundle(id).getHeaders()));
             } catch (JSONException e) {
                 e.printStackTrace();
             }
             
+        } else if (resourceId.equals("showWiredBundles")) {
+            String str_id = request.getParameter("id");
+            long id = Long.parseLong(str_id);
+            Bundle bundle = bundleContext.getBundle(id);
+            
+            ServiceReference reference = bundle.getBundleContext().getServiceReference(PackageAdmin.class.getName());
+            try {
+                
+               
+                PackageAdmin packageAdmin = (PackageAdmin) bundle.getBundleContext().getService(reference);
+                
+
+                
+                
+                //importing
+                Set<PackageBundlePair> importingPairs =  getImportingPairs(packageAdmin, bundle);
+
+                //importingPairs may have same values, so we override the equals method in PackageBundlePairJSONObject
+                Set<PackageBundlePairJSONObject> importingPairSet = new HashSet<PackageBundlePairJSONObject>();
+                
+                int i=0;
+                for (PackageBundlePair pair : importingPairs) {
+                    
+                    String pname = pair.exportedPackage.getName() + " (Version="+ pair.exportedPackage.getVersion()+")";
+                    String bname = pair.bundle.getSymbolicName() + " (id=" + pair.bundle.getBundleId() + ")";
+                    
+                    importingPairSet.add(new PackageBundlePairJSONObject(i,pname,bname));
+                    
+                    i++;
+                }
+                PackageBundlePairGridJSONObject importingPairGrid = new PackageBundlePairGridJSONObject(importingPairSet);
+                
+                
+                //exporting
+                Set<PackageBundlePair> exportingPairs = getExportingPairs(packageAdmin, bundle);
+                
+                Set<PackageBundlePairJSONObject> exportingPairSet = new HashSet<PackageBundlePairJSONObject>();
+                
+                int j=0;
+                for (PackageBundlePair pair : exportingPairs) {
+                    
+                    String pname = pair.exportedPackage.getName() + " (Version="+ pair.exportedPackage.getVersion()+")";
+                    String bname = pair.bundle.getSymbolicName() + " (id=" + pair.bundle.getBundleId() + ")";
+                    
+                    exportingPairSet.add(new PackageBundlePairJSONObject(j, pname,bname));
+                    
+                    j++;
+                }
+                PackageBundlePairGridJSONObject exportingPairGrid = new PackageBundlePairGridJSONObject(exportingPairSet);
+                
+                
+                //construct result
+                WiredBundlesJSONObject wb = new WiredBundlesJSONObject(importingPairGrid,exportingPairGrid);
+
+                PrintWriter writer = response.getWriter();
+                writer.print(wb);
+                
+            } catch (JSONException e) {
+                e.printStackTrace();
+            } finally {
+                bundle.getBundleContext().ungetService(reference);
+            }
+                
+                
         } else if (resourceId.equals("installAction")) {
             String result = processInstallAction(new ActionResourceRequest(request), bundleContext);
             PrintWriter writer = response.getWriter();
             writer.print(result);
             
+            
+            
+        } else if (resourceId.equals("showSysBundles")) {
+            
+            Bundle[] bundles = bundleContext.getBundles();
+
+            // list contains bundles converted from Bundle objects
+            ArrayList<OSGiBundle> OSGiBundleList = new ArrayList<OSGiBundle>();
+
+            
+            // convert Bundle to OSGiBundle
+            for (Bundle bundle : bundles) {
+                if (checkSysBundle(bundle)){
+                    OSGiBundle osgiBundle = new OSGiBundle(bundle);
+                    OSGiBundleList.add(osgiBundle);
+                }
+            }
+            
+            try {
+                JSONObject grid = new BundleGridJSONObject(OSGiBundleList);
+                PrintWriter writer = response.getWriter();
+                writer.print(grid);
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+            
+            
         }
     }
+    
+    
+    private Set<PackageBundlePair> getImportingPairs(PackageAdmin packageAdmin, Bundle bundle) {
+        BundleDescription description = new BundleDescription(bundle.getHeaders());
+        
+        Set<PackageBundlePair> importingPairs = new HashSet<PackageBundlePair>();
+        
+        // handle static wire via Import-Package
+        List<BundleDescription.ImportPackage> imports = description.getExternalImports();
+        for (BundleDescription.ImportPackage packageImport : imports) {
+            ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(packageImport.getName());
+            if (exportedPackages!=null){
+                for (ExportedPackage exportedPackage : exportedPackages) {
+                    Bundle[] importingBundles = exportedPackage.getImportingBundles();
+                    if (importingBundles != null) {
+                        for (Bundle importingBundle : importingBundles) {
+                            if (importingBundle == bundle) {
+                                importingPairs.add(new PackageBundlePair(exportedPackage, exportedPackage.getExportingBundle()));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        // handle dynamic wire via DynamicImport-Package
+//        if (!description.getDynamicImportPackage().isEmpty()) {
+//            for (Bundle b : bundle.getBundleContext().getBundles()) {
+//                ExportedPackage[] exports = packageAdmin.getExportedPackages(b);
+//                Bundle wiredBundle = getWiredBundle(bundle, exports);
+//                if (exports != null) {
+//                    for (ExportedPackage exportedPackage : exports) {
+//                        Bundle[] importingBundles = exportedPackage.getImportingBundles();
+//                        if (importingBundles != null) {
+//                            for (Bundle importingBundle : importingBundles) {
+//                                if (importingBundle == bundle) {
+//                                    pbPairs.put(exportedPackage, wiredBundle);
+//                                }
+//                            }
+//                        }
+//                    }
+//                }
+//              
+//            }
+//        }
+        
+        return importingPairs;
+    }
+    
+
+
+    
+    private Set<PackageBundlePair> getExportingPairs(PackageAdmin packageAdmin, Bundle bundle) {
+        
+        Set<PackageBundlePair> exportingPairs = new HashSet<PackageBundlePair> ();
+        
+        ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(bundle);
+        
+        if (exportedPackages != null){
+            for (ExportedPackage exportedPackage : exportedPackages) {
+                Bundle[] importingBundles = exportedPackage.getImportingBundles();
+                if (importingBundles != null) {
+                    for (Bundle importingBundle : importingBundles) {
+                        exportingPairs.add(new PackageBundlePair(exportedPackage, importingBundle));
+                        
+                    }
+                }
+            }
+        }
+        
+        
+        return exportingPairs;
+
+    }
+    
+    class PackageBundlePair {
+        final ExportedPackage exportedPackage;
+        final Bundle bundle;
+        
+        PackageBundlePair(ExportedPackage exportedPackage,Bundle bundle ){
+            this.exportedPackage = exportedPackage;
+            this.bundle = bundle;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
 
+            final PackageBundlePair other = (PackageBundlePair) obj;
+            if (this.exportedPackage != other.exportedPackage && (this.exportedPackage == null || !this.exportedPackage.equals(other.exportedPackage))) {
+                return false;
+            }
+            if (this.bundle != other.bundle && (this.bundle == null || !this.bundle.equals(other.bundle))) {
+                return false;
+            }
+
+            return true;
+            
+        }
+        
+        @Override
+        public int hashCode() {
+            int hash = 11;
+            hash = 17* hash + (exportedPackage != null ? exportedPackage.hashCode():0);
+            hash = 17 * hash + (bundle != null ? bundle.hashCode():0);
+
+            return hash;
+        }
+        
+    }
+    
     private String processInstallAction(ActionRequest request, BundleContext bundleContext) throws PortletException, IOException {
         if (!PortletFileUpload.isMultipartContent(request)) {
             throw new PortletException("Expected file upload");

Modified: geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/webapp/WEB-INF/view/BundlesView.jsp
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/webapp/WEB-INF/view/BundlesView.jsp?rev=1073353&r1=1073352&r2=1073353&view=diff
==============================================================================
--- geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/webapp/WEB-INF/view/BundlesView.jsp (original)
+++ geronimo/server/branches/3.0-M2/plugins/console/osgi-portlets/src/main/webapp/WEB-INF/view/BundlesView.jsp Tue Feb 22 14:53:19 2011
@@ -62,17 +62,16 @@ function hideLoadingDIV(){
 <style type="text/css">
 @import "/dojo/dojo/resources/dojo.css";
 @import "/dojo/dijit/themes/tundra/tundra.css";
+@import "/dojo/dijit/themes/tundra/document.css";
 @import "/dojo/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css";
+@import "/dojo/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css";
 @import "/dojo/dojox/grid/enhanced/resources/tundraEnhancedGrid.css";
 
-#grid1 {
-	border: 1px solid #333;
-	width: 800px;
-	margin: 0px;
-	height: 300px;
-	font-size: 0.9em;
-	font-family: Geneva, Arial, Helvetica, sans-serif;
-}
+@import "/dojo/dijit/themes/claro/claro.css";		
+@import "/dojo/dijit/themes/claro/document.css";
+@import "/dojo/dojox/grid/enhanced/resources/claro/EnhancedGrid.css";
+
+
 </style>
 
 
@@ -89,9 +88,20 @@ function hideLoadingDIV(){
 <%
 	//show single bundle
     ResourceURL ajaxResourceURL3 = renderResponse.createResourceURL();
-    ajaxResourceURL3.setResourceID("showSingleBundle");
+    ajaxResourceURL3.setResourceID("showManifest");
+%>
+<%
+	//show sys bundle
+    ResourceURL ajaxResourceURL4 = renderResponse.createResourceURL();
+    ajaxResourceURL4.setResourceID("showSysBundles");
+%>
+<%
+	//show wired bundle
+    ResourceURL ajaxResourceURL5 = renderResponse.createResourceURL();
+    ajaxResourceURL5.setResourceID("showWiredBundles");
 %>
 
+
 <script type="text/javascript">
 	dojo.require("dojo.parser");
 	dojo.require("dojo.io.iframe"); 
@@ -104,96 +114,209 @@ function hideLoadingDIV(){
 	dojo.require("dojox.grid.cells.dijit");
 	dojo.require("dojox.grid.enhanced.plugins.Menu");
 
-	dojo.addOnLoad(function() {
-		dojo.connect(dijit.byId("grid1"), "onRowClick", grid1RowClick);
-	});
-
-    function actionPerform(actionName,loadHandle){
-    	//get all selected lines
-    	var selectedItems=dijit.byId("grid1").selection.getSelected();
-    	if(selectedItems.length){
-    		showLoadingDIV();
-
-        	//construct action json string
-    		var actionJsonStr='{action:'+actionName+',items:[';
-    		var i;var id;
-    		for(i=0;i<selectedItems.length-1;i++){
-    			if(selectedItems[i]!=null){
-    				id=dijit.byId("grid1").store.getValue(selectedItems[i],"id");
-    				actionJsonStr=actionJsonStr+'{id:'+id+'},';
-    			}
-    		}
-    		//The last item does not need a comma
-    		id=dijit.byId("grid1").store.getValue(selectedItems[selectedItems.length-1],"id");
-    		actionJsonStr=actionJsonStr+'{id:'+id+'}'+']}';	
+
+    dojo.require("dijit.layout.ContentPane");
+    dojo.require("dijit.layout.TabContainer");
+	
+
+	
+    function actionPerform(actionName, id){
+    	
+    	showLoadingDIV();
+
+        //construct action json string
+    	var actionJsonStr='{action:'+actionName+',id:'+id+'}';
     		
-    		//alert(actionJsonStr);
+    	//alert(actionJsonStr);
     	
-    		//ajax call to portlet's serveResource()
-    		var postArgs={
-    			url:"<%=ajaxResourceURL%>formId="+formID,
-    			handleAs:"json",
-    			content:{bundlesActionParam:actionJsonStr},
-    			load:loadHandle
-    		};
-    		dojo.xhrPost(postArgs);			
-    	} else {
-			// need better show err msg
-			alert("at least select one item");
-       	}
-    }
+    	//ajax call to portlet's serveResource()
+    	var postArgs={
+    		url:"<%=ajaxResourceURL%>formId="+formID,
+    		handleAs:"json",
+    		content:{bundlesActionParam:actionJsonStr},
+    		sync:true,
+    		load:function(response, ioArgs){
+    			//update the items which done an action
+    			var updatedItem = response;		
+
+    			if(updatedItem != null){
+    				if (updatedItem.state == "err") {
+    					// need better way to show err msg
+    					alert(updatedItem.id + "err");
+    							
+    				}else if(updatedItem.state == "Uninstalled") {
+    					dijit.byId("usrBundlesGrid").store.fetchItemByIdentity({
+    						identity:updatedItem.id,
+    						onItem:function(item){
+    							dijit.byId("usrBundlesGrid").store.deleteItem(item);
+    						}
+    					});
+    				}else { // start/stop/refresh action results
+    					dijit.byId("usrBundlesGrid").store.fetchItemByIdentity({
+    						identity:updatedItem.id,
+    						onItem:function(item){
+    							dijit.byId("usrBundlesGrid").store.setValue(item,"state",updatedItem.state);
+    						}
+    					});
+    				}
+    			}
+    		}
+    	};
 
-    //function for update items after action
-    function  actionUpdate(response, ioArgs){
-		//update the items which done an action
-		var updatedItems=response.items;			
-		dojo.forEach(updatedItems,function(updatedItem){
-			if(updatedItem!=null){
-				if (updatedItem.state == "err") {
-					// need better way to show err msg
-					alert(updatedItem.id + "err");
-					
-				}else if(updatedItem.state == "Uninstalled") {
-					dijit.byId("grid1").store.fetchItemByIdentity({
-						identity:updatedItem.id,
-						onItem:function(item){
-							dijit.byId("grid1").store.deleteItem(item);
-						}
-					});
-				}else { // start or stop actions
-					dijit.byId("grid1").store.fetchItemByIdentity({
-						identity:updatedItem.id,
-						onItem:function(item){
-							dijit.byId("grid1").store.setValue(item,"state",updatedItem.state);
-						}
-					});
-				}
-			}
-		});
+    	dojo.xhrPost(postArgs);			
 
-		hideLoadingDIV();
-	}
 
+    	hideLoadingDIV();
+    }
 
-	function grid1RowClick(e){
-        document.getElementById("singleBundleDiv").style.display = "block";
-		
-		var id=dijit.byId("grid1").getItem(e.rowIndex).id;
+
+	function showManifest(id,symbolicName){
+		showLoadingDIV();
+
+		manifestTitle.innerHTML = "<b>The Manifest of "+symbolicName+"</b>";
+        
 		//ajax call to portlet's serveResource()
 		var postArgs={
 			url:"<%=ajaxResourceURL3%>formId="+formID,
 			handleAs:"text",
 			content:{id:id},
+			sync:true,
 			load:function(response, ioArgs){
 				var headers=dojo.fromJson(response);
 				var newStore = new dojo.data.ItemFileWriteStore({data:headers}); 
-				dijit.byId("headersgrid").setStore(newStore);
+				dijit.byId("manifestGrid").setStore(newStore);
+
+				dijit.byId("bundlesTab").selectChild(dijit.byId("manifestPane"));
+								
+			}
+		};
+		dojo.xhrPost(postArgs);	
+
+		hideLoadingDIV();	
+	}
+
+	function showWiredBundles(id,symbolicName){
+		showLoadingDIV();
+
+		wiredBundlesTitle.innerHTML = "<b>The Wired Bundles of "+symbolicName+"</b>";
+        
+		//ajax call to portlet's serveResource()
+		var postArgs={
+			url:"<%=ajaxResourceURL5%>formId="+formID,
+			handleAs:"json",
+			content:{id:id},
+			sync:true,
+			load:function(response, ioArgs){
+				var importingBundles = response.importingBundles;
+				var newImportingStore = new dojo.data.ItemFileWriteStore({data:importingBundles}); 
+				dijit.byId("wiredBundlesImportingGrid").setStore(newImportingStore);
+
+				var exportingBundles = response.exportingBundles;
+				var newExportingStore = new dojo.data.ItemFileWriteStore({data:exportingBundles}); 
+				dijit.byId("wiredBundlesExportingGrid").setStore(newExportingStore);
+				
+				dijit.byId("bundlesTab").selectChild(dijit.byId("wiredBundlesPane"));
 								
 			}
 		};
-		dojo.xhrPost(postArgs);		
+		dojo.xhrPost(postArgs);	
+
+		hideLoadingDIV();	
 	}
 
+	function showSysBundles(){
+		showLoadingDIV();
+
+		if (dijit.byId("sysBundlesPane")!=null){
+			var sysBndCP = dijit.byId("sysBundlesPane");
+			dijit.byId("bundlesTab").selectChild(sysBndCP);
+		} else {
+			// add new ContentPane to TabContainer
+		    var bndTC = dijit.byId("bundlesTab");
+			var sysBndCP = new dijit.layout.ContentPane({
+									id: "sysBundlesPane",
+									title: "Geronimo System Bundles",
+									content: "<p id='sysfilter' style='margin-top:5px;margin-bottom:5px'>Filter by Symbolic Name:</p>",
+									style: "height:500",
+									closable: true
+								});
+			bndTC.addChild(sysBndCP, 1); // insert to the index "1"
+			bndTC.selectChild(sysBndCP);
+				
+			// add filter TextBox
+			var filteredSysName = new dijit.form.TextBox();
+			filteredSysName.placeAt("sysfilter",1);		// position "0" is for the string "Filter by Symbolic Name:"
+	
+			// add DataGrid
+			var jsonStore = new dojo.data.ItemFileWriteStore({data:{items:[]}});
+		        
+		    var layout = [{
+		            field: 'id',
+		            name: 'Id',
+		            width: '50px'
+		        },
+		        {
+		            field: 'symbolicName',
+		            name: 'Symbolic Name',
+		            width: 'auto'
+		        },
+		        {
+		            field: 'version',
+		            name: 'Version',
+		            width: '120px'
+		        },
+		        {
+		            field: 'state',
+		            name: 'State',
+		            width: '60px'
+		        },
+		        {
+		            field: '_item',
+		            name: 'Utilities',
+		            width: '250px',
+		            formatter: fmtUtilCell
+		        }];
+	
+		    var sysBndGrid = new dojox.grid.DataGrid({
+		            query: {
+		                id: '*'
+		            },
+		            store: jsonStore,
+		            clientSort: true,
+		            //rowSelector: '20px',
+		            structure: layout,
+		            style: "height:450"
+		        },
+		        document.createElement('div')
+		    );
+		    
+		    sysBndGrid.placeAt(sysBndCP.domNode,2);  //sysBndCP.set("content",sysBndGrid.domNode);  //will replace the content
+		    sysBndGrid.startup();
+		        
+	
+			//connect the event handler with the dijit
+		    dojo.connect(filteredSysName, "onKeyUp", function(evt) {
+		        var fitlerStr = filteredSysName.get("value") ;
+		        sysBndGrid.filter({symbolicName: "*" + fitlerStr + "*"});       
+				dojo.stopEvent(evt);
+		    });
+	
+		    //ajax call to portlet's serveResource()
+		    var postArgs={
+				url:"<%=ajaxResourceURL4%>",
+				handleAs:"text",
+				sync:true,
+				load:function(response, ioArgs){
+					var sysbundles = dojo.fromJson(response);
+					var newStore = new dojo.data.ItemFileWriteStore({data:sysbundles}); 
+					sysBndGrid.setStore(newStore);
+				}
+			};
+			dojo.xhrPost(postArgs);	
+		}
+		
+		hideLoadingDIV();
+	}
 
 	
 	function installBundle(){
@@ -206,7 +329,8 @@ function hideLoadingDIV(){
 			form: dojo.byId("installForm"),
 			load: function(response, ioArgs){
 				var bundle=dojo.fromJson(response);
-				var item=dijit.byId("grid1").store.newItem(bundle);
+				var item=dijit.byId("usrBundlesGrid").store.newItem(bundle);
+				dijit.byId("usrBundlesGrid").sort();
 			}
 		});
 		
@@ -214,122 +338,180 @@ function hideLoadingDIV(){
 	}
 </script> 
 
+<div>
+This portlet shows the general user bundles installed in geronimo. To see all the system bundles, <a href="#" onclick="showSysBundles()">click here</a> (Loading might be slow).
+</div>
+<br/>
+
+<!-- bundles tab container : Start -->
+<div jsid="bundlesTab" id="bundlesTab" dojoType="dijit.layout.TabContainer" style="width: 100%" doLayout="false">
 
+<div jsid="bundlesPane" id="bundlesPane" dojoType="dijit.layout.ContentPane" title="General Bundles" selected="true">   
+
+	<!-- bundles bar -->
+	<table border="0" style="width:100%;margin:0px 0px;">
+	    <tr>
+	    	
+	        <td>
+	        	<form id="installForm" enctype="multipart/form-data" method="POST">
+	            Install New:
+	            <input type="file" style="width:200px" name="bundleFile" />
+				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+		        
+		        <fmt:message key="osgi.bundle.install.startAfterInstalled" />:
+		        <input type="checkbox" dojoType="dijit.form.CheckBox" name="startAfterInstalled" value="yes" align="middle" />
+		        
+		        
+		        <!-- Don't allow user set start level for now
+		        <fmt:message key="osgi.bundle.startLevel" />:
+		        <input type="text" dojoType="dijit.form.TextBox" style="width: 3em;" name="startLevel" size="4" />
+		        &nbsp;
+		        -->
+		        <!--  can not align in IE
+		        <button dojoType="dijit.form.Button">
+			    	<script type="dojo/method" event="onClick" args="evt">
+						installBundle();
+		    		</script>
+		        </button> 
+		        -->
+		        <input type="button" style="width:80px" onClick="installBundle()" value="<fmt:message key='osgi.bundle.install.install'/>"></input>
+	        	</form>
+	        </td>
+	        
+	        
+	    	<!-- filter -->
+			<td align="right">
+				<label>Filter by Symbolic Name: </label>
+				<div type="text" jsid="filteredSymbolicName" id="filteredSymbolicName" dojoType="dijit.form.TextBox" style="width: 16em;">
+					<script type="dojo/method" event="onKeyUp" args="evt">
+					var fitlerStr = dojo.byId("filteredSymbolicName").value;
+        			dijit.byId("usrBundlesGrid").filter({
+            			symbolicName: "*" + fitlerStr + "*"     
+        			});
+				</script>
+				</div>
+			</td>
+			
+	        
+	    
+			
+		</tr> 
+	</table>
+	
+	
+	
+	<!-- bundles grid -->
+	<script>
+		jsonData=${GridJSONObject};
+		usrBundlesStroe=new dojo.data.ItemFileWriteStore({data:jsonData});
+		
+	    function fmtActionsCell(item, idx){
+			var innerhtml = "";
+			if (item.state == "Installed" || item.state == "Resolved"){
+				innerhtml += "<a href='#' onclick=actionPerform('start',"+item.id+")>start</a>&nbsp;";
+			}
+			if (item.state == "Active"){
+				innerhtml += "<a href='#' onclick=actionPerform('stop',"+item.id+")>stop</a>&nbsp;";
+			}
+			
+			innerhtml += "<a href='#' onclick=actionPerform('uninstall',"+item.id+")>uninstall</a>&nbsp;";
+			
+			innerhtml += "<a href='#' onclick=actionPerform('refresh',"+item.id+")>refresh</a>&nbsp;";
+			
+			return innerhtml;
+		}
+	    function fmtUtilCell(item, idx){
+			var innerhtml = "";
+			
+			innerhtml += "<a href='#' onclick=showManifest("+item.id+",'"+item.symbolicName+"')>View Manifest</a>&nbsp;";
+			if (item.id !=0){
+				if (item.state == "Active"){
+					innerhtml += "<a href='#' onclick=showWiredBundles("+item.id+",'"+item.symbolicName+"')>View Wired Bundles</a>&nbsp;";
+				}
+			}
+			
+			return innerhtml;
+		}
+	</script>
+	
+	<table jsid="usrBundlesGrid" id="usrBundlesGrid" dojoType="dojox.grid.DataGrid"
+		store="usrBundlesStroe" selectable="true" 
+		query="{ id: '*' }" queryOptions ="{ignoreCase: true}" sortFields="[{attribute:'id',descending:true}]" 
+		style="width:100%;height:450;margin:0px 0px;">
+		<thead>
+			<tr>
+				<th field="id" width="50px">Id</th>
+				<th field="symbolicName" width="50%">Symbolic Name</th>
+				<th field="version" width="120px">Version</th>
+				<th field="state" width="60px">State</th>
+				<th field="_item" formatter="fmtActionsCell" width="160px">Actions</th>  <!-- "_item" represents an item in store -->
+				<th field="_item" formatter="fmtUtilCell" width="250px">Utilities</th>
+			</tr>
+		</thead>
+	</table>
 
 
-<!-- Installing a bundle -->
-<div dojoType="dijit.TitlePane" title="Install a bundle" >
-<form id="installForm" enctype="multipart/form-data" method="POST">
-<table border="0" style="width:100%;margin:10px 0px;">
-    <tr>
-        <td align="right" valign="top" width="20%">Bundle:</td>
-	    <td><input type="file" style="width:200px" name="bundleFile" />
-	    	<br/>
-	        <input type="checkbox" dojoType="dijit.form.CheckBox" name="startAfterInstalled" value="yes" align="middle" />
-	        <fmt:message key="osgi.bundle.install.startAfterInstalled" />
-	        <br/>
-	        <input type="text" dojoType="dijit.form.TextBox" style="width: 3em;" name="startLevel" size="4" />
-	        <fmt:message key="osgi.bundle.startLevel" />  
-	        <br/>
-	        <button dojoType="dijit.form.Button"><fmt:message key="osgi.bundle.install.install"/>
-		    	<script type="dojo/method" event="onClick" args="evt">
-					installBundle();
-		    	</script>
-	        </button> 
-	    </td>
-	</tr>
-</table>
-</form>
 </div>
 
 
-<br/>
 
-<!-- bundles bar -->
-<table border="0" style="width:100%;margin:0px 0px;">
-    <tr>
-    	<!-- actions -->
-        <td>
-            <label>Select all: </label>
-			<div id="cbxall" name="cbxall" dojoType="dijit.form.CheckBox" value="all">
-				<script type="dojo/method" event="onChange" args="newvalue">
-					if (newvalue == true) {
-						dijit.byId("grid1").rowSelectCell.toggleAllSelection(true);
-					}else {
-						dijit.byId("grid1").rowSelectCell.toggleAllSelection(false);
-					}
-				</script>
-			</div>
-			&nbsp;
-			<button dojoType="dijit.form.Button">Start
-				<script type="dojo/method" event="onClick" args="evt">
-					actionPerform("start",actionUpdate);
-				</script>
-			</button>
-			<button dojoType="dijit.form.Button">Stop
-				<script type="dojo/method" event="onClick" args="evt">
-					actionPerform("stop",actionUpdate);
-				</script>
-			</button>
-			<button dojoType="dijit.form.Button">Uninstall
-				<script type="dojo/method" event="onClick" args="evt">
-					actionPerform("uninstall",actionUpdate);
-				</script>
-			</button>
-		</td>
-		
-		<!-- filter -->
-		<td align="right">
-			<label>Filter by Symbolic Name: </label>
-			<div type="text" jsid="filteredSymbolicName" id="filteredSymbolicName" dojoType="dijit.form.TextBox" style="width: 16em;">
-				<script type="dojo/method" event="onKeyUp" args="evt">
-				    var fitlerStr = dojo.byId("filteredSymbolicName").value;
-        			dijit.byId("grid1").filter({
-            			symbolicName: "*" + fitlerStr + "*"     
-        			});       
-					dojo.stopEvent(evt);
-				</script>
-			</div>
-		</td>
-	</tr> 
-</table>
-
-<!-- bundles grid -->
-<script>
-var jsonData=${GridJSONObject};
-var jsonStore=new dojo.data.ItemFileWriteStore({data:jsonData});
-</script>
-
-<table jsid="grid1" id="grid1" dojoType="dojox.grid.EnhancedGrid"
-	plugins="{indirectSelection: true}" store="jsonStore"
-	query="{ id: '*' }" style="width:100%;margin:0px 0px;">
-	<thead>
-		<tr>
-			<th field="id">Id</th>
-			<th field="symbolicName" width="50%">Symbolic Name</th>
-			<th field="version">Version</th>
-			<th field="state">State</th>
-		</tr>
-	</thead>
-</table>
-<br/>
+<!-- Bundle Manifest -->
+<div jsid="manifestPane" id="manifestPane" dojoType="dijit.layout.ContentPane" title="Bundle Manifest">
+	<script>
+		manifestStore = new dojo.data.ItemFileWriteStore({data:{items:[]}});
+	</script>
+	<div id="manifestTitle"></div>
+	<div>
+	<table jsid="manifestGrid" id="manifestGrid" dojoType="dojox.grid.DataGrid"
+		store="manifestStore" escapeHTMLInData="false" selectable="true" 
+		style="width:100%;height:450;margin:0px 0px;">
+		<thead>
+			<tr>
+				<th field="hkey" width="20%">Header Name</th>
+				<th field="hvalue" width="80%">Header Value</th>
+			</tr>
+		</thead>
+	</table>
+	</div>
+</div>
+
 
+<!-- Wired Bundles -->
+<div jsid="wiredBundlesPane" id="wiredBundlesPane" dojoType="dijit.layout.ContentPane" title="Wired Bundles">
+	<script>
+		wiredBundlesStore = new dojo.data.ItemFileWriteStore({data:{items:[]}});
+	</script>
+	<div id="wiredBundlesTitle"></div>
+	<div>
+	Importing Packages from Bundles:<br/>
+	<table jsid="wiredBundlesImportingGrid" id="wiredBundlesImportingGrid" dojoType="dojox.grid.DataGrid"
+		store="wiredBundlesStore" escapeHTMLInData="false" selectable="true" 
+		style="width:100%;height:300;margin:0px 0px;">
+		<thead>
+			<tr>
+				<th field="pname" width="50%">Importing Packages</th>
+				<th field="bname" width="50%">From Bundles</th>
+			</tr>
+		</thead>
+	</table>
+	
+	<br/>
+	Exporting Packages to Bundles:<br/>
+	<table jsid="wiredBundlesExportingGrid" id="wiredBundlesExportingGrid" dojoType="dojox.grid.DataGrid"
+		store="wiredBundlesStore" escapeHTMLInData="false" selectable="true" 
+		style="width:100%;height:300;margin:0px 0px;">
+		<thead>
+			<tr>
+				<th field="pname" width="50%">Exporting Packages</th>
+				<th field="bname" width="50%">To Bundles</th>
+			</tr>
+		</thead>
+	</table>
+	</div>
+</div>
 
-<!-- headers grid -->
-<script>
-var headersStore=new dojo.data.ItemFileWriteStore({data:""});
-</script>
-<div id="singleBundleDiv" style="display:none">
-<table jsid="headersgrid" id="headersgrid" dojoType="dojox.grid.DataGrid"
-	store="headersStore" autoHeight="true" escapeHTMLInData="false" style="width:100%;margin:0px 0px;">
-	<thead>
-		<tr>
-			<th field="hkey" width="20%">Header Name</th>
-			<th field="hvalue" width="80%">Header Value</th>
-		</tr>
-	</thead>
-</table>
 </div>
+<!-- bundles tab container : End -->
 
 </div>