felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1424592 - in /felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole: ResourceBundleManager.java WebConsoleAdapter.java
Date Thu, 20 Dec 2012 17:05:51 GMT
Author: cziegeler
Date: Thu Dec 20 17:05:51 2012
New Revision: 1424592

URL: http://svn.apache.org/viewvc?rev=1424592&view=rev
Log:
Add resource bundle handling for titles

Added:
    felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java
  (with props)
Modified:
    felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/WebConsoleAdapter.java

Added: felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java?rev=1424592&view=auto
==============================================================================
--- felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java
(added)
+++ felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java
Thu Dec 20 17:05:51 2012
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.status.impl.webconsole;
+
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+
+
+/**
+ * The ResourceBundleManager manages resource bundle instance per OSGi Bundle.
+ * It contains a local cache, for bundles, but when a bundle is being unistalled,
+ * its resources stored in the cache are cleaned up.
+ */
+public class ResourceBundleManager implements BundleListener
+{
+
+    private final BundleContext bundleContext;
+
+    private final Map<Long, ResourceBundle> resourceBundleCaches;
+
+
+    /**
+     * Creates a new object and adds self as a bundle listener
+     *
+     * @param bundleContext the bundle context of the Web Console.
+     */
+    public ResourceBundleManager( final BundleContext bundleContext )
+    {
+        this.bundleContext = bundleContext;
+        this.resourceBundleCaches = new HashMap<Long, ResourceBundle>();
+
+        bundleContext.addBundleListener( this );
+    }
+
+
+    /**
+     * Removes the bundle lister.
+     */
+    public void dispose()
+    {
+        bundleContext.removeBundleListener( this );
+    }
+
+
+    /**
+     * This method is used to retrieve a /cached/ instance of the i18n resource associated
+     * with a given bundle.
+     *
+     * @param provider the bundle, provider of the resources
+     * @param locale the requested locale.
+     */
+    public ResourceBundle getResourceBundle( final Bundle provider ) {
+        ResourceBundle cache;
+        final Long key = new Long( provider.getBundleId() );
+        synchronized ( resourceBundleCaches ) {
+            cache = resourceBundleCaches.get( key );
+            if ( cache == null && !resourceBundleCaches.containsKey(key)) {
+                cache = this.loadResourceBundle(provider);
+                resourceBundleCaches.put( key, cache );
+            }
+        }
+
+        return cache;
+    }
+
+
+    // ---------- BundleListener
+
+    /**
+     * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
+     */
+    public final void bundleChanged( BundleEvent event )
+    {
+        if ( event.getType() == BundleEvent.STOPPED )
+        {
+            final Long key = new Long( event.getBundle().getBundleId() );
+            synchronized ( resourceBundleCaches )
+            {
+                resourceBundleCaches.remove( key );
+            }
+        }
+    }
+
+    private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
+
+    private ResourceBundle loadResourceBundle(final Bundle bundle) {
+        final String path = "_" + DEFAULT_LOCALE.toString(); //$NON-NLS-1$
+        final URL source = ( URL ) getResourceBundleEntries(bundle).get( path );
+        if ( source != null ) {
+            try {
+                return new PropertyResourceBundle( source.openStream() );
+            } catch ( final IOException ignore ) {
+                // ignore
+            }
+        }
+        return null;
+    }
+
+
+    private synchronized Map getResourceBundleEntries(final Bundle bundle)
+    {
+        String file = ( String ) bundle.getHeaders().get( Constants.BUNDLE_LOCALIZATION );
+        if ( file == null )
+        {
+            file = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+        }
+
+        // remove leading slash
+        if ( file.startsWith( "/" ) ) //$NON-NLS-1$
+        {
+            file = file.substring( 1 );
+        }
+
+        // split path and base name
+        int slash = file.lastIndexOf( '/' );
+        String fileName = file.substring( slash + 1 );
+        String path = ( slash <= 0 ) ? "/" : file.substring( 0, slash ); //$NON-NLS-1$
+
+        HashMap resourceBundleEntries = new HashMap();
+
+        Enumeration locales = bundle.findEntries( path, fileName + "*.properties", false
); //$NON-NLS-1$
+        if ( locales != null )
+        {
+            while ( locales.hasMoreElements() )
+            {
+                URL entry = ( URL ) locales.nextElement();
+
+                // calculate the key
+                String entryPath = entry.getPath();
+                final int start = entryPath.lastIndexOf( '/' ) + 1 + fileName.length(); //
path, slash and base name
+                final int end = entryPath.length() - 11; // .properties suffix
+                entryPath = entryPath.substring( start, end );
+
+                // the default language is "name.properties" thus the entry
+                // path is empty and must default to "_"+DEFAULT_LOCALE
+                if (entryPath.length() == 0) {
+                    entryPath = "_" + DEFAULT_LOCALE; //$NON-NLS-1$
+                }
+
+                // only add this entry, if the "language" is not provided
+                // by the main bundle or an earlier bound fragment
+                if (!resourceBundleEntries.containsKey( entryPath )) {
+                    resourceBundleEntries.put( entryPath, entry );
+                }
+            }
+        }
+
+        return resourceBundleEntries;
+    }
+}

Propchange: felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/ResourceBundleManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/WebConsoleAdapter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/WebConsoleAdapter.java?rev=1424592&r1=1424591&r2=1424592&view=diff
==============================================================================
--- felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/WebConsoleAdapter.java
(original)
+++ felix/sandbox/cziegeler/status-printer/src/main/java/org/apache/felix/status/impl/webconsole/WebConsoleAdapter.java
Thu Dec 20 17:05:51 2012
@@ -23,6 +23,7 @@ import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Map;
+import java.util.ResourceBundle;
 
 import org.apache.felix.status.PrinterMode;
 import org.apache.felix.status.StatusPrinter;
@@ -46,8 +47,11 @@ public class WebConsoleAdapter implement
 
     private final Map<ServiceReference, ServiceRegistration> registrations = new HashMap<ServiceReference,
ServiceRegistration>();
 
+    private final ResourceBundleManager rbManager;
+
     public WebConsoleAdapter(final BundleContext btx) throws InvalidSyntaxException {
         this.bundleContext = btx;
+        this.rbManager = new ResourceBundleManager(btx);
         this.cfgPrinterTracker = new ServiceTracker( this.bundleContext,
                 this.bundleContext.createFilter("(|(" + Constants.OBJECTCLASS + "=" + ConsoleConstants.INTERFACE_CONFIGURATION_PRINTER
+ ")" +
                         "(&(" + ConsoleConstants.PLUGIN_LABEL + "=*)(&("
@@ -68,13 +72,20 @@ public class WebConsoleAdapter implement
             }
             this.registrations.clear();
         }
+        this.rbManager.dispose();
     }
 
     public void add(final ServiceReference reference, final Object service) {
         final ConfigurationPrinterAdapter cpa = ConfigurationPrinterAdapter.createAdapter(service,
reference);
         if ( cpa != null && cpa.title != null ) {
             if ( cpa.title.startsWith("%") ) {
-                cpa.title = cpa.title.substring(1);
+                final String key = cpa.title.substring(1);
+                final ResourceBundle rb = this.rbManager.getResourceBundle(reference.getBundle());
+                if ( rb == null || !rb.containsKey(key) ) {
+                    cpa.title = key;
+                } else {
+                    cpa.title = rb.getString(key);
+                }
             }
             if ( cpa.label == null ) {
                 cpa.label = cpa.title;



Mime
View raw message