Save This Page
Home » org.apache.sling.launchpad.base-2.2.0-source-release » org.apache.sling.launchpad.base.impl.bootstrapcommands » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    *   http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   package org.apache.sling.launchpad.base.impl.bootstrapcommands;
   20   
   21   import java.io.BufferedReader;
   22   import java.io.File;
   23   import java.io.FileInputStream;
   24   import java.io.FileOutputStream;
   25   import java.io.IOException;
   26   import java.io.InputStream;
   27   import java.io.InputStreamReader;
   28   import java.util.ArrayList;
   29   import java.util.List;
   30   
   31   import org.apache.felix.framework.Logger;
   32   import org.osgi.framework.BundleContext;
   33   
   34   public class BootstrapCommandFile {
   35       /** Name of file used to store our execution timestamp */
   36       public static final String DATA_FILENAME = BootstrapCommandFile.class.getSimpleName() + "_timestamp.txt";
   37   
   38       /** Prefix for comments in command files */
   39       public static final String COMMENT_PREFIX = "#";
   40   
   41       private final File commandFile;
   42       private final Logger logger;
   43   
   44       private static final List<Command> commandPrototypes = new ArrayList<Command>();
   45       static {
   46           commandPrototypes.add(new UninstallBundleCommand());
   47       }
   48   
   49       /** Will load our commands from specified file, if found */
   50       public BootstrapCommandFile(Logger logger, File cmdFile) {
   51           this.logger = logger;
   52           this.commandFile = cmdFile;
   53       }
   54   
   55       /** True if we have a command file that needs to be executed, based on its
   56        *  file timestamp and stored timstamp
   57        */
   58       boolean anythingToExecute(BundleContext ctx) {
   59           boolean result = false;
   60           if(commandFile != null && commandFile.exists() && commandFile.canRead()) {
   61               final long cmdTs = commandFile.lastModified();
   62               long lastExecution = 0;
   63               try {
   64                   lastExecution = loadTimestamp(ctx);
   65               } catch(IOException ioe) {
   66                   logger.log(Logger.LOG_INFO, "IOException reading timestamp", ioe);
   67               }
   68               if(cmdTs > lastExecution) {
   69                   logger.log(Logger.LOG_INFO,
   70                           "Command file timestamp > stored timestamp, need to execute commands ("
   71                           + commandFile.getAbsolutePath() + ")");
   72                   result = true;
   73               }
   74           }
   75           if(!result) {
   76               logger.log(Logger.LOG_INFO,
   77                       "Command file absent or older than last execution timestamp, nothing to execute ("
   78                       + commandFile.getAbsolutePath() + ")");
   79           }
   80           return result;
   81       }
   82   
   83       /** Execute commands if needed, and store execution timestamp
   84        *  @return number of commands executed */
   85       public int execute(BundleContext ctx) throws IOException {
   86           int count = 0;
   87           if(anythingToExecute(ctx)) {
   88               InputStream is = null;
   89               try {
   90                   is = new FileInputStream(commandFile);
   91                   final List<Command> cmds = parse(is);
   92                   for(Command cmd : cmds) {
   93                       try {
   94                           logger.log(Logger.LOG_DEBUG, "Executing command: " + cmd);
   95                           cmd.execute(logger, ctx);
   96                           count++;
   97                       } catch(Exception e) {
   98                           logger.log(Logger.LOG_WARNING, "Exception in command execution (" + cmd + ") :" + e);
   99                       }
  100                   }
  101               } finally {
  102                   if(is != null) {
  103                       try {
  104                           is.close();
  105                       } catch(IOException ignore) {
  106                           // ignore
  107                       }
  108                   }
  109               }
  110   
  111               try {
  112                   storeTimestamp(ctx);
  113               } catch(IOException ioe) {
  114                   logger.log(Logger.LOG_WARNING, "IOException while storing timestamp", ioe);
  115               }
  116           }
  117           return count;
  118       }
  119   
  120       /** Parse commands from supplied input stream.
  121        *  Does not close the stream */
  122       List<Command> parse(InputStream is) throws IOException {
  123           final List<Command> result = new ArrayList<Command>();
  124           final BufferedReader r = new BufferedReader(new InputStreamReader(is));
  125           String line = null;
  126           while( (line = r.readLine()) != null) {
  127               line = line.trim();
  128               if(line.length() > 0 && !line.startsWith(COMMENT_PREFIX)) {
  129                   Command toAdd = null;
  130                   for(Command proto : commandPrototypes) {
  131                       toAdd = proto.parse(line);
  132                       if(toAdd != null) {
  133                           break;
  134                       }
  135                   }
  136                   if (toAdd == null) {
  137                       throw new Command.ParseException("Invalid command '" + line + "'");
  138                   }
  139                   result.add(toAdd);
  140               }
  141           }
  142           return result;
  143       }
  144   
  145       /** Return the data file to use for our timestamp */
  146       private File getTimestampFile(BundleContext ctx) {
  147           return ctx.getDataFile(DATA_FILENAME);
  148       }
  149   
  150       /** Return our stored timestamp */
  151       private long loadTimestamp(BundleContext ctx) throws IOException {
  152           long result = 0;
  153           final File f = getTimestampFile(ctx);
  154           if(f.exists()) {
  155               FileInputStream fis = null;
  156               try {
  157                   fis = new FileInputStream(f);
  158                   byte[] bytes = new byte[20];
  159                   int len = fis.read(bytes);
  160                   if(len > 0) {
  161                       result = Long.parseLong(new String(bytes, 0, len));
  162                   }
  163               } finally {
  164                   if(fis != null) {
  165                       fis.close();
  166                   }
  167               }
  168           }
  169           return result;
  170       }
  171   
  172       private void storeTimestamp(BundleContext ctx) throws IOException {
  173           final File f = getTimestampFile(ctx);
  174           FileOutputStream fos = null;
  175           try {
  176               fos = new FileOutputStream(f);
  177               fos.write(String.valueOf(System.currentTimeMillis()).getBytes());
  178           } finally {
  179               if(fos != null) {
  180                   fos.close();
  181               }
  182           }
  183       }
  184   }

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