You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2007/07/23 11:30:22 UTC

svn commit: r558672 - in /felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences: ./ impl/

Author: cziegeler
Date: Mon Jul 23 02:30:21 2007
New Revision: 558672

URL: http://svn.apache.org/viewvc?view=rev&rev=558672
Log:
Use service tracker to track persistence implementation (WiP).

Added:
    felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/BackingStoreManager.java   (with props)
Modified:
    felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/PreferencesImpl.java
    felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/DataFileBackingStoreImpl.java
    felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesManager.java
    felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesServiceImpl.java

Added: felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/BackingStoreManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/BackingStoreManager.java?view=auto&rev=558672
==============================================================================
--- felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/BackingStoreManager.java (added)
+++ felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/BackingStoreManager.java Mon Jul 23 02:30:21 2007
@@ -0,0 +1,31 @@
+/*
+ * 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.sandbox.preferences;
+
+
+/**
+ * Get the backing store.
+ */
+public interface BackingStoreManager {
+
+    /**
+     * Return the current backing store.
+     */
+    BackingStore getStore();
+}

Propchange: felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/BackingStoreManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/BackingStoreManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/PreferencesImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/PreferencesImpl.java?view=diff&rev=558672&r1=558671&r2=558672
==============================================================================
--- felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/PreferencesImpl.java (original)
+++ felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/PreferencesImpl.java Mon Jul 23 02:30:21 2007
@@ -58,8 +58,8 @@
     /** The description for this preferences. */
     protected final PreferencesDescription description;
 
-    /** The backing store. */
-    protected final BackingStore store;
+    /** The backing store manager. */
+    protected final BackingStoreManager storeManager;
 
     /** The change set keeps track of all changes. */
     protected final ChangeSet changeSet = new ChangeSet();
@@ -67,13 +67,13 @@
     /**
      * Construct the root node of the tree.
      * @param d The unique description.
-     * @param store The backing store.
+     * @param storeManager The backing store.
      */
-    public PreferencesImpl(PreferencesDescription d, BackingStore store) {
+    public PreferencesImpl(PreferencesDescription d, BackingStoreManager storeManager) {
         this.parent = null;
         this.name = "";
         this.description = d;
-        this.store = store;
+        this.storeManager = storeManager;
     }
 
     /**
@@ -85,7 +85,7 @@
         this.parent = p;
         this.name = name;
         this.description = p.description;
-        this.store = p.store;
+        this.storeManager = p.storeManager;
     }
 
     /**
@@ -130,6 +130,13 @@
     }
 
     /**
+     * Return the backing store manager.
+     */
+    public BackingStoreManager getBackingStoreManager() {
+        return this.storeManager;
+    }
+
+    /**
      * Check if this node is still valid.
      * It gets invalid if it has been removed.
      */
@@ -589,7 +596,7 @@
      */
     public synchronized void flush() throws BackingStoreException {
         this.checkValidity();
-        this.store.store(this);
+        this.storeManager.getStore().store(this);
         this.changeSet.clear();
     }
 
@@ -598,8 +605,8 @@
      */
     public synchronized void sync() throws BackingStoreException {
         this.checkValidity();
-        this.store.update(this);
-        this.store.store(this);
+        this.storeManager.getStore().update(this);
+        this.storeManager.getStore().store(this);
     }
 
     /**

Modified: felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/DataFileBackingStoreImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/DataFileBackingStoreImpl.java?view=diff&rev=558672&r1=558671&r2=558672
==============================================================================
--- felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/DataFileBackingStoreImpl.java (original)
+++ felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/DataFileBackingStoreImpl.java Mon Jul 23 02:30:21 2007
@@ -28,6 +28,8 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.felix.sandbox.preferences.BackingStore;
+import org.apache.felix.sandbox.preferences.BackingStoreManager;
 import org.apache.felix.sandbox.preferences.PreferencesDescription;
 import org.apache.felix.sandbox.preferences.PreferencesImpl;
 import org.osgi.framework.BundleContext;
@@ -139,7 +141,7 @@
             final PreferencesDescription desc = this.getDescription(current);
             if ( desc != null ) {
                 if ( desc.getBundleId().equals(bundleId) ) {
-                    final PreferencesImpl root = new PreferencesImpl(desc, this);
+                    final PreferencesImpl root = new PreferencesImpl(desc, new DummyBackingStoreManager(this));
                     try {
                         final FileInputStream fis = new FileInputStream(current);
                         this.read(root, fis);
@@ -162,7 +164,7 @@
         final File file = this.getFile(desc);
         if ( file.exists() ) {
             try {
-                final PreferencesImpl root = new PreferencesImpl(desc, this);
+                final PreferencesImpl root = new PreferencesImpl(desc, new DummyBackingStoreManager(this));
                 final FileInputStream fis = new FileInputStream(file);
                 this.read(root, fis);
                 fis.close();
@@ -190,5 +192,21 @@
         buffer.append(".ser");
         final File file = new File(this.rootDirectory, buffer.toString());
         return file;
+    }
+
+    protected static final class DummyBackingStoreManager implements BackingStoreManager {
+
+        protected final BackingStore store;
+
+        public DummyBackingStoreManager(BackingStore s) {
+            this.store = s;
+        }
+
+        /**
+         * @see org.apache.felix.sandbox.preferences.BackingStoreManager#getStore()
+         */
+        public BackingStore getStore() {
+            return this.store;
+        }
     }
 }

Modified: felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesManager.java?view=diff&rev=558672&r1=558671&r2=558672
==============================================================================
--- felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesManager.java (original)
+++ felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesManager.java Mon Jul 23 02:30:21 2007
@@ -23,6 +23,7 @@
 import java.util.Map;
 
 import org.apache.felix.sandbox.preferences.BackingStore;
+import org.apache.felix.sandbox.preferences.BackingStoreManager;
 import org.apache.felix.sandbox.preferences.PreferencesImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
@@ -30,10 +31,11 @@
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
 import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
 import org.osgi.service.prefs.BackingStoreException;
 import org.osgi.service.prefs.PreferencesService;
+import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * This activator registers itself as a service factory for the
@@ -43,7 +45,8 @@
 public class PreferencesManager
     implements BundleActivator,
                BundleListener,
-               ServiceFactory {
+               ServiceFactory,
+               BackingStoreManager {
 
     /** The map of already created services. For each client bundle
      * a new service is created.
@@ -54,7 +57,16 @@
     protected BundleContext context;
 
     /** The backing store service tracker. */
-    protected BackingStore store;
+    protected ServiceTracker storeTracker;
+
+    /** The service tracker for the log service. */
+    protected ServiceTracker logTracker;
+
+    /** The default store which is used if no service can be found. */
+    protected BackingStore defaultStore;
+
+    /** Tracking count for the store tracker to detect changes. */
+    protected int storeTrackingCount = -1;
 
     /**
      * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
@@ -64,7 +76,7 @@
             final Long bundleId = new Long(event.getBundle().getBundleId());
             synchronized ( this.services ) {
                 try {
-                    this.store.remove(bundleId);
+                    this.getStore().remove(bundleId);
                 } catch (BackingStoreException ignore) {
                     // we ignore this for now
                 }
@@ -79,39 +91,17 @@
     public void start(BundleContext context) throws Exception {
         this.context = context;
 
-        // create our backing store - check if a service is registered
-        final ServiceReference ref = context.getServiceReference(BackingStore.class.getName());
-        if ( ref != null ) {
-            this.store = (BackingStore)context.getService(ref);
-        }
-        // if no store is registered use the default data file implementation
-        if ( this.store == null ) {
-            this.store = new DataFileBackingStoreImpl(this.context);
-        }
+        // track the log service using a ServiceTracker
+        this.logTracker = new ServiceTracker( context, LogService.class.getName(), null );
+        this.logTracker.open();
+
+        // create the tracker for our backing store
+        this.storeTracker = new ServiceTracker( context, BackingStore.class.getName(), null);
+        this.storeTracker.open();
 
         // register this activator as a bundle lister
         context.addBundleListener(this);
 
-        // check which bundles are available
-        final Long[] availableBundleIds = this.store.availableBundles();
-
-        // now check the bundles, for which we have preferences, if they are still
-        // in service and delete the preferences where the bundles are out of service.
-        // we synchronize on services in order to get not disturbed by a bundle event
-        synchronized ( this.services ) {
-            for(int i=0; i<availableBundleIds.length; i++) {
-                final Long bundleId = availableBundleIds[i];
-                final Bundle bundle = context.getBundle(bundleId.longValue());
-                if (bundle == null || bundle.getState() == Bundle.UNINSTALLED) {
-                    try {
-                        this.store.remove(bundleId);
-                    } catch (BackingStoreException ignore) {
-                        // we ignore this for now
-                    }
-                }
-            }
-        }
-
         // finally register the service factory for the preferences service
         context.registerService(PreferencesService.class.getName(), this, null);
     }
@@ -129,7 +119,19 @@
             }
             this.services.clear();
         }
-        this.store = null;
+        // stop tracking store service
+        if ( this.storeTracker != null ) {
+            this.storeTracker.close();
+            this.storeTracker = null;
+        }
+        this.defaultStore = null;
+
+        // stop tracking log service
+        if ( this.logTracker != null ) {
+            this.logTracker.close();
+            this.logTracker = null;
+        }
+
         this.context = null;
     }
 
@@ -146,7 +148,7 @@
 
             if (service == null) {
                 // create a new service instance
-                service = new PreferencesServiceImpl(bundleId, this.store);
+                service = new PreferencesServiceImpl(bundleId, this);
                 this.services.put(bundleId, service);
             }
             return service;
@@ -176,9 +178,70 @@
         while ( i.hasNext() ) {
             final PreferencesImpl prefs = (PreferencesImpl)i.next();
             try {
-                this.store.store(prefs);
+                this.getStore().store(prefs);
             } catch (BackingStoreException ignore) {
                 // we ignore this
+            }
+        }
+    }
+
+    protected void log( int level, String message, Throwable t ) {
+        final LogService log = ( LogService ) this.logTracker.getService();
+        if ( log != null ) {
+            log.log( level, message, t );
+            return;
+        }
+    }
+
+    /**
+     * @see org.apache.felix.sandbox.preferences.BackingStoreManager#getStore()
+     */
+    public BackingStore getStore() {
+        // has the service changed?
+        int currentCount = this.storeTracker.getTrackingCount();
+        BackingStore service = (BackingStore) this.storeTracker.getService();
+        if ( service != null && this.storeTrackingCount < currentCount ) {
+            this.storeTrackingCount = currentCount;
+            this.cleanupStore(service);
+        }
+        if ( service == null ) {
+            // no service available use default store
+            if ( this.defaultStore == null ) {
+                synchronized ( this ) {
+                    if ( this.defaultStore == null ) {
+                        this.defaultStore = new DataFileBackingStoreImpl(this.context);
+                        this.cleanupStore(this.defaultStore);
+                    }
+                }
+            }
+            service = this.defaultStore;
+        }
+        this.log(LogService.LOG_INFO, "Using store " + service.getClass().getName(), null);
+        return service;
+    }
+
+    /**
+     * Clean up the store and remove preferences for deleted bundles.
+     * @param store
+     */
+    protected void cleanupStore(BackingStore store) {
+        // check which bundles are available
+        final Long[] availableBundleIds = store.availableBundles();
+
+        // now check the bundles, for which we have preferences, if they are still
+        // in service and delete the preferences where the bundles are out of service.
+        // we synchronize on services in order to get not disturbed by a bundle event
+        synchronized ( this.services ) {
+            for(int i=0; i<availableBundleIds.length; i++) {
+                final Long bundleId = availableBundleIds[i];
+                final Bundle bundle = this.context.getBundle(bundleId.longValue());
+                if (bundle == null || bundle.getState() == Bundle.UNINSTALLED) {
+                    try {
+                        store.remove(bundleId);
+                    } catch (BackingStoreException ignore) {
+                        // we ignore this for now
+                    }
+                }
             }
         }
     }

Modified: felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesServiceImpl.java?view=diff&rev=558672&r1=558671&r2=558672
==============================================================================
--- felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesServiceImpl.java (original)
+++ felix/sandbox/cziegeler/preferences/src/main/java/org/apache/felix/sandbox/preferences/impl/PreferencesServiceImpl.java Mon Jul 23 02:30:21 2007
@@ -24,7 +24,7 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.felix.sandbox.preferences.BackingStore;
+import org.apache.felix.sandbox.preferences.BackingStoreManager;
 import org.apache.felix.sandbox.preferences.PreferencesDescription;
 import org.apache.felix.sandbox.preferences.PreferencesImpl;
 import org.osgi.service.prefs.BackingStoreException;
@@ -45,17 +45,17 @@
     /** The service id for the bundle this service belongs to. */
     protected final Long bundleId;
 
-    /** The backing store. */
-    protected final BackingStore store;
+    /** The backing store manager. */
+    protected final BackingStoreManager storeManager;
 
     public PreferencesServiceImpl(Long id,
-                                  BackingStore store) {
+                                  BackingStoreManager storeManager) {
         this.bundleId = id;
-        this.store = store;
+        this.storeManager = storeManager;
         try {
             // load prefs first
             PreferencesImpl[] prefs = null;
-            prefs = this.store.loadAll(this.bundleId);
+            prefs = this.storeManager.getStore().loadAll(this.bundleId);
             for(int i=0;i<prefs.length;i++) {
                 if ( prefs[i].getDescription().getIdentifier() == null ) {
                     this.systemTree = prefs[i];
@@ -73,7 +73,7 @@
      */
     public synchronized Preferences getSystemPreferences() {
         if ( this.systemTree == null ) {
-            this.systemTree = new PreferencesImpl(new PreferencesDescription(this.bundleId, null), this.store);
+            this.systemTree = new PreferencesImpl(new PreferencesDescription(this.bundleId, null), this.storeManager);
         }
         // sync with latest version from store
         try {
@@ -91,7 +91,7 @@
         PreferencesImpl result = (PreferencesImpl) this.trees.get(name);
         // if the tree does not exist yet, create it
         if (result == null) {
-            result = new PreferencesImpl(new PreferencesDescription(this.bundleId, name), this.store);
+            result = new PreferencesImpl(new PreferencesDescription(this.bundleId, name), this.storeManager);
             this.trees.put(name, result);
         }
         // sync with latest version from store