You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2008/01/30 08:56:53 UTC

svn commit: r616675 - in /incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal: ContentLoaderService.java JcrResourceResolverFactoryImpl.java loader/Loader.java

Author: cziegeler
Date: Tue Jan 29 23:56:53 2008
New Revision: 616675

URL: http://svn.apache.org/viewvc?rev=616675&view=rev
Log:
CLOSED - issue SLING-212: Content is loaded with wrong mime type if mime type service is not available 
https://issues.apache.org/jira/browse/SLING-212

Added:
    incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ContentLoaderService.java   (with props)
Modified:
    incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
    incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/loader/Loader.java

Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ContentLoaderService.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ContentLoaderService.java?rev=616675&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ContentLoaderService.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ContentLoaderService.java Tue Jan 29 23:56:53 2008
@@ -0,0 +1,189 @@
+/*
+ * 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.sling.jcr.resource.internal;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.resource.internal.loader.Loader;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>ContentLoaderService</code> is the service
+ * providing the following functionality:
+ * <ul>
+ * <li>Bundle listener to load initial content and manage OCM mapping
+ * descriptors provided by bundles.
+ * <li>Fires OSGi EventAdmin events on behalf of internal helper objects
+ * </ul>
+ *
+ * @scr.component metatype="false"
+ * @scr.property name="service.description" value="Sling
+ *               Content Loader Implementation"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ */
+public class ContentLoaderService implements BundleListener {
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * The JCR Repository we access to resolve resources
+     *
+     * @scr.reference
+     */
+    private SlingRepository repository;
+
+    /**
+     * The MimeTypeService used by the initial content initialContentLoader to
+     * resolve MIME types for files to be installed.
+     *
+     * @scr.reference
+     */
+    private MimeTypeService mimeTypeService;
+
+    /**
+     * Administrative sessions used to check item existence.
+     */
+    private Session adminSession;
+
+    /**
+     * The initial content loader which is called to load initial content up
+     * into the repository when the providing bundle is installed.
+     */
+    private Loader initialContentLoader;
+
+    // ---------- BundleListener -----------------------------------------------
+
+    /**
+     * Loads and unloads any components provided by the bundle whose state
+     * changed. If the bundle has been started, the components are loaded. If
+     * the bundle is about to stop, the components are unloaded.
+     *
+     * @param event The <code>BundleEvent</code> representing the bundle state
+     *            change.
+     */
+    public void bundleChanged(BundleEvent event) {
+
+        //
+        // NOTE:
+        // This is synchronous - take care to not block the system !!
+        //
+
+        switch (event.getType()) {
+            case BundleEvent.STARTING: // STARTED:
+                // register content when the bundle content is available
+                // as node types are registered when the bundle is installed
+                // we can safely add the content at this point.
+                try {
+                    Session session = getAdminSession();
+                    initialContentLoader.registerBundle(session,
+                        event.getBundle());
+                } catch (Throwable t) {
+                    log.error(
+                        "bundleChanged: Problem loading initial content of bundle "
+                            + event.getBundle().getSymbolicName() + " ("
+                            + event.getBundle().getBundleId() + ")", t);
+                }
+
+            case BundleEvent.UNINSTALLED:
+                initialContentLoader.unregisterBundle(event.getBundle());
+                break;
+        }
+    }
+
+    // ---------- Implementation helpers --------------------------------------
+
+    /** Returns the MIME type from the MimeTypeService for the given name */
+    public String getMimeType(String name) {
+        // local copy to not get NPE despite check for null due to concurrent
+        // unbind
+        MimeTypeService mts = mimeTypeService;
+        return (mts != null) ? mts.getMimeType(name) : null;
+    }
+
+    // ---------- SCR Integration ---------------------------------------------
+
+    /** Activates this component, called by SCR before registering as a service */
+    protected void activate(ComponentContext componentContext) {
+        this.initialContentLoader = new Loader(this);
+
+        componentContext.getBundleContext().addBundleListener(this);
+
+        try {
+            final Session session = getAdminSession();
+
+            Bundle[] bundles = componentContext.getBundleContext().getBundles();
+            for (Bundle bundle : bundles) {
+                if ((bundle.getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
+                    // load content for bundles which are neither INSTALLED nor
+                    // UNINSTALLED
+                    initialContentLoader.registerBundle(session, bundle);
+                }
+
+            }
+        } catch (Throwable t) {
+            log.error("activate: Problem while loading initial content and"
+                + " registering mappings for existing bundles", t);
+        }
+    }
+
+    /** Deativates this component, called by SCR to take out of service */
+    protected void deactivate(ComponentContext componentContext) {
+        componentContext.getBundleContext().removeBundleListener(this);
+
+        if ( this.initialContentLoader != null ) {
+            this.initialContentLoader.dispose();
+            this.initialContentLoader = null;
+        }
+
+        if ( adminSession != null ) {
+            this.adminSession.logout();
+            this.adminSession = null;
+        }
+    }
+
+    // ---------- internal helper ----------------------------------------------
+
+    /** Returns the JCR repository used by this factory */
+    protected SlingRepository getRepository() {
+        return repository;
+    }
+
+    /**
+     * Returns an administrative session to the given workspace or the default
+     * workspaces if the supplied name is <code>null</code>.
+     */
+    private synchronized Session getAdminSession()
+            throws RepositoryException {
+        if ( adminSession == null ) {
+            adminSession = getRepository().loginAdministrative(null);
+        }
+        return adminSession;
+    }
+
+
+}

Propchange: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ContentLoaderService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ContentLoaderService.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java?rev=616675&r1=616674&r2=616675&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java Tue Jan 29 23:56:53 2008
@@ -35,14 +35,12 @@
 import org.apache.commons.collections.bidimap.TreeBidiMap;
 import org.apache.sling.api.resource.ResourceProvider;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.commons.mime.MimeTypeService;
 import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
 import org.apache.sling.jcr.resource.internal.helper.Mapping;
 import org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry;
 import org.apache.sling.jcr.resource.internal.helper.bundle.BundleResourceProvider;
 import org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderEntry;
-import org.apache.sling.jcr.resource.internal.loader.Loader;
 import org.apache.sling.osgi.commons.OsgiUtil;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
@@ -65,7 +63,7 @@
  * descriptors provided by bundles.
  * <li>Fires OSGi EventAdmin events on behalf of internal helper objects
  * </ul>
- * 
+ *
  * @scr.component immediate="true" label="%resource.resolver.name"
  *                description="%resource.resolver.description"
  * @scr.property name="service.description" value="Sling
@@ -89,7 +87,7 @@
      * maven plugin and the sling management console cannot handle empty
      * multivalue properties at the moment. So we just add a dummy direct
      * mapping.
-     * 
+     *
      * @scr.property values.1="/-/"
      */
     private static final String PROP_VIRTUAL = "resource.resolver.virtual";
@@ -114,30 +112,22 @@
 
     /**
      * The JCR Repository we access to resolve resources
-     * 
+     *
      * @scr.reference
      */
     private SlingRepository repository;
 
     /**
      * The OSGi EventAdmin service used to dispatch events
-     * 
+     *
      * @scr.reference cardinality="0..1" policy="dynamic"
      */
     private EventAdmin eventAdmin;
 
-    /**
-     * The MimeTypeService used by the initial content initialContentLoader to
-     * resolve MIME types for files to be installed.
-     * 
-     * @scr.reference cardinality="0..1" policy="dynamic"
-     */
-    private MimeTypeService mimeTypeService;
-
     // list of ResourceProvider services bound before activation of the
     // component
     private List<ServiceReference> delayedResourceProviders = new LinkedList<ServiceReference>();
-    
+
     private ComponentContext componentContext;
 
     /**
@@ -162,17 +152,11 @@
      * Map of administrative sessions used to check item existence. Indexed by
      * workspace name. The map is filled on-demand. The sessions are closed when
      * the factory is deactivated.
-     * 
+     *
      * @see #itemReallyExists(Session, String)
      */
     private Map<String, Session> adminSessions = new HashMap<String, Session>();
 
-    /**
-     * The initial content loader which is called to load initial content up
-     * into the repository when the providing bundle is installed.
-     */
-    private Loader initialContentLoader;
-
     private ResourceProviderEntry rootProviderEntry;
 
     private Map<Long, BundleResourceProvider> bundleResourceProviderMap = new HashMap<Long, BundleResourceProvider>();
@@ -202,7 +186,7 @@
      * Loads and unloads any components provided by the bundle whose state
      * changed. If the bundle has been started, the components are loaded. If
      * the bundle is about to stop, the components are unloaded.
-     * 
+     *
      * @param event The <code>BundleEvent</code> representing the bundle state
      *            change.
      */
@@ -214,21 +198,6 @@
         //
 
         switch (event.getType()) {
-            case BundleEvent.STARTING: // STARTED:
-                // register content when the bundle content is available
-                // as node types are registered when the bundle is installed
-                // we can safely add the content at this point.
-                try {
-                    Session session = getAdminSession(null);
-                    initialContentLoader.registerBundle(session,
-                        event.getBundle());
-                } catch (Throwable t) {
-                    log.error(
-                        "bundleChanged: Problem loading initial content of bundle "
-                            + event.getBundle().getSymbolicName() + " ("
-                            + event.getBundle().getBundleId() + ")", t);
-                }
-
             case BundleEvent.STARTED:
                 // register resource provider for the started bundle
                 addBundleResourceProvider(event.getBundle());
@@ -238,10 +207,6 @@
                 // remove resource provider after the bundle has stopped
                 removeBundleResourceProvider(event.getBundle());
                 break;
-
-            case BundleEvent.UNINSTALLED:
-                initialContentLoader.unregisterBundle(event.getBundle());
-                break;
         }
     }
 
@@ -249,7 +214,7 @@
 
     /**
      * Fires an OSGi event through the EventAdmin service.
-     * 
+     *
      * @param sourceBundle The Bundle from which the event originates. This may
      *            be <code>null</code> if there is no originating bundle.
      * @param eventName The name of the event
@@ -320,14 +285,6 @@
         }
     }
 
-    /** Returns the MIME type from the MimeTypeService for the given name */
-    public String getMimeType(String name) {
-        // local copy to not get NPE despite check for null due to concurrent
-        // unbind
-        MimeTypeService mts = mimeTypeService;
-        return (mts != null) ? mts.getMimeType(name) : null;
-    }
-
     /** If uri is a virtual URI returns the real URI, otherwise returns null */
     String virtualToRealUri(String virtualUri) {
         return (virtualURLMap != null)
@@ -395,8 +352,6 @@
         this.componentContext = componentContext;
         this.serviceReference = componentContext.getServiceReference();
 
-        this.initialContentLoader = new Loader(this);
-
         componentContext.getBundleContext().addBundleListener(this);
 
         try {
@@ -404,12 +359,6 @@
 
             Bundle[] bundles = componentContext.getBundleContext().getBundles();
             for (Bundle bundle : bundles) {
-                if ((bundle.getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
-                    // load content for bundles which are neither INSTALLED nor
-                    // UNINSTALLED
-                    initialContentLoader.registerBundle(session, bundle);
-                }
-
                 if (bundle.getState() == Bundle.ACTIVE) {
                     // add bundle resource provider for active bundles
                     addBundleResourceProvider(bundle);
@@ -478,8 +427,6 @@
     protected void deactivate(ComponentContext componentContext) {
         componentContext.getBundleContext().removeBundleListener(this);
 
-        initialContentLoader.dispose();
-
         Session[] sessions = adminSessions.values().toArray(
             new Session[adminSessions.size()]);
         adminSessions.clear();
@@ -492,10 +439,10 @@
 
     protected void bindResourceProvider(ServiceReference reference) {
         if (componentContext == null) {
-            
+
             // delay binding resource providers if called before activation
             delayedResourceProviders.add(reference);
-            
+
         } else {
             String[] roots = OsgiUtil.toStringArray(reference.getProperty(ResourceProvider.ROOTS));
             if (roots != null && roots.length > 0) {

Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/loader/Loader.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/loader/Loader.java?rev=616675&r1=616674&r2=616675&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/loader/Loader.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/loader/Loader.java Tue Jan 29 23:56:53 2008
@@ -41,7 +41,7 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl;
+import org.apache.sling.jcr.resource.internal.ContentLoaderService;
 import org.osgi.framework.Bundle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -64,7 +64,7 @@
     /** default log */
     private final Logger log = LoggerFactory.getLogger(Loader.class);
 
-    private JcrResourceResolverFactoryImpl jcrContentHelper;
+    private ContentLoaderService jcrContentHelper;
     private XmlReader xmlReader;
     private JsonReader jsonReader;
     private Map<String, List<String>> delayedReferences;
@@ -72,7 +72,7 @@
     // bundles whose registration failed and should be retried
     private List<Bundle> delayedBundles;
 
-    public Loader(JcrResourceResolverFactoryImpl jcrContentHelper) {
+    public Loader(ContentLoaderService jcrContentHelper) {
         this.jcrContentHelper = jcrContentHelper;
         this.delayedReferences = new HashMap<String, List<String>>();
         this.delayedBundles = new LinkedList<Bundle>();
@@ -351,7 +351,7 @@
                 type = DEFAULT_CONTENT_TYPE;
             }
         }
-        
+
         // ensure sensible last modification date
         if (lastModified <= 0) {
             lastModified = System.currentTimeMillis();