Save This Page
Home » org.apache.sling.launchpad.base-2.2.0-source-release » org.apache.sling.launchpad.base.impl » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.sling.launchpad.base.impl;
   18   
   19   import java.io.File;
   20   import java.io.FileInputStream;
   21   import java.io.FileOutputStream;
   22   import java.io.IOException;
   23   import java.io.InputStream;
   24   import java.io.ObjectInputStream;
   25   import java.io.ObjectOutputStream;
   26   import java.util.ArrayList;
   27   import java.util.Iterator;
   28   
   29   import org.apache.felix.framework.Logger;
   30   import org.osgi.framework.BundleContext;
   31   import org.osgi.framework.FrameworkEvent;
   32   import org.osgi.framework.FrameworkListener;
   33   import org.osgi.framework.ServiceEvent;
   34   import org.osgi.framework.ServiceListener;
   35   import org.osgi.framework.ServiceReference;
   36   import org.osgi.service.deploymentadmin.DeploymentAdmin;
   37   import org.osgi.service.deploymentadmin.DeploymentException;
   38   
   39   /**
   40    * This is the deployment package installer.
   41    * It is a delayed service that runs as soon as the framework is started
   42    * and the deployment admin is available.
   43    * It looks then in {@link BootstrapInstaller#PATH_BUNDLES} for
   44    * deloyment packages and tries to install/update them.
   45    *
   46    */
   47   public class DeploymentPackageInstaller implements ServiceListener, FrameworkListener {
   48   
   49       public static final String DEPLOYMENT_ADMIN = DeploymentAdmin.class.getName();
   50   
   51       public static final String EXTENSION = ".dp";
   52   
   53       public static final String DATA_FILE = "dpi.data";
   54   
   55       private boolean frameworkStarted = false;
   56       private boolean serviceAvailable = false;
   57       private boolean deployed = false;
   58   
   59       private final BundleContext bundleContext;
   60       private final Logger logger;
   61       private final ResourceProvider resourceProvider;
   62   
   63       private DeploymentAdmin deploymentAdmin;
   64       private ServiceReference deploymentAdminReference;
   65   
   66       public DeploymentPackageInstaller(final BundleContext bundleContext,
   67               Logger logger, ResourceProvider resourceProvider) {
   68           this.logger = logger;
   69           this.resourceProvider = resourceProvider;
   70           this.bundleContext = bundleContext;
   71       }
   72   
   73       /**
   74        * Wait for the deployment admin service.
   75        * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
   76        */
   77       public synchronized void serviceChanged(ServiceEvent event) {
   78           if ( event.getType() == ServiceEvent.REGISTERED && !this.deployed ) {
   79               this.deploymentAdminReference = this.bundleContext.getServiceReference(DEPLOYMENT_ADMIN);
   80               this.deploymentAdmin = (DeploymentAdmin) this.bundleContext.getService(this.deploymentAdminReference);
   81               this.serviceAvailable = true;
   82               if ( this.frameworkStarted ) {
   83                   this.deploy();
   84               }
   85           }
   86   
   87       }
   88   
   89       /**
   90        * Wait for the framework start.
   91        * @see org.osgi.framework.FrameworkListener#frameworkEvent(org.osgi.framework.FrameworkEvent)
   92        */
   93       public synchronized void frameworkEvent(FrameworkEvent event) {
   94           if (event.getType() == FrameworkEvent.STARTED && !this.deployed) {
   95               this.frameworkStarted = true;
   96               if ( this.serviceAvailable ) {
   97                   this.deploy();
   98               }
   99           }
  100   
  101       }
  102   
  103       /**
  104        * Deploy the deployment packages.
  105        */
  106       @SuppressWarnings("unchecked")
  107       private void deploy() {
  108           ArrayList<String> installedPcks = null;
  109           final File dataFile = this.bundleContext.getDataFile(DATA_FILE);
  110           if ( dataFile != null && dataFile.exists() ) {
  111               try {
  112                   final FileInputStream fis = new FileInputStream(dataFile);
  113                   try {
  114                       final ObjectInputStream ois = new ObjectInputStream(fis);
  115                       try {
  116                           installedPcks = (ArrayList<String>) ois.readObject();
  117                       } catch (ClassNotFoundException e) {
  118                           // this can never happen so we just log
  119                           logger.log(Logger.LOG_ERROR, "Class not found!", e);
  120                       } finally {
  121                           try {
  122                               ois.close();
  123                           } catch (IOException ignore) {}
  124                       }
  125                   } finally {
  126                       try {
  127                           fis.close();
  128                       } catch (IOException ignore) {}
  129                   }
  130               } catch (IOException ioe) {
  131                   logger.log(Logger.LOG_ERROR, "IOException during reading of deployed packages.", ioe);
  132               }
  133           }
  134           try {
  135               Iterator<String> res = resourceProvider.getChildren(BootstrapInstaller.PATH_BUNDLES);
  136               while (res.hasNext()) {
  137   
  138                   String path = res.next();
  139   
  140                   if ( path.endsWith(EXTENSION) ) {
  141                       // check if we already installed this
  142                       final int pos = path.lastIndexOf('/');
  143                       final String name = path.substring(pos + 1);
  144   
  145                       if ( installedPcks != null && installedPcks.contains(name) ) {
  146                           continue;
  147                       }
  148   
  149                       // install this as a deployment package
  150                       final InputStream ins = resourceProvider.getResourceAsStream(path);
  151                       if (ins == null) {
  152                           continue;
  153                       }
  154                       try {
  155                           this.deploymentAdmin.installDeploymentPackage(ins);
  156                           logger.log(Logger.LOG_INFO, "Deployment Package "
  157                                   + " installed from " + path);
  158                       } catch (DeploymentException e) {
  159                           logger.log(Logger.LOG_ERROR, "Deployment Package installation from "
  160                                   + path + " failed", e);
  161                       }
  162                       if ( installedPcks == null ) {
  163                           installedPcks = new ArrayList<String>();
  164                       }
  165                       installedPcks.add(name);
  166                   }
  167               }
  168   
  169           } catch (Throwable t) {
  170               logger.log(Logger.LOG_ERROR, "Unexpected error during package deployment.", t);
  171           }
  172           // update status
  173           if ( installedPcks != null ) {
  174               try {
  175                   final FileOutputStream fos = new FileOutputStream(dataFile);
  176                   try {
  177                       final ObjectOutputStream oos = new ObjectOutputStream(fos);
  178                       try {
  179                           oos.writeObject(installedPcks);
  180                       } finally {
  181                           try {
  182                               oos.close();
  183                           } catch (IOException ignore) {}
  184                       }
  185                   } finally {
  186                       try {
  187                           fos.close();
  188                       } catch (IOException ignore) {}
  189                   }
  190               } catch (IOException ioe) {
  191                   logger.log(Logger.LOG_ERROR, "IOException during writing deployed packages.", ioe);
  192               }
  193           }
  194           // now clean up
  195           this.deployed = true;
  196           this.bundleContext.ungetService(this.deploymentAdminReference);
  197           this.bundleContext.removeFrameworkListener(this);
  198           this.bundleContext.removeServiceListener(this);
  199           this.deploymentAdmin = null;
  200           this.deploymentAdminReference = null;
  201       }
  202   }

Save This Page
Home » org.apache.sling.launchpad.base-2.2.0-source-release » org.apache.sling.launchpad.base.impl » [javadoc | source]