View Javadoc

1   package com.atlassian.plugin.osgi.container.impl;
2   
3   import java.io.File;
4   import java.io.IOException;
5   
6   import com.atlassian.plugin.osgi.container.OsgiContainerException;
7   import com.atlassian.plugin.osgi.container.OsgiPersistentCache;
8   
9   import org.apache.commons.io.FileUtils;
10  import org.apache.commons.lang.Validate;
11  import org.slf4j.Logger;
12  import org.slf4j.LoggerFactory;
13  
14  /**
15   * Default implementation of persistent cache.  Handles clearing of directories if an upgrade has been detected.
16   *
17   * @since 2.2.0
18   */
19  public class DefaultOsgiPersistentCache implements OsgiPersistentCache
20  {
21      private final File osgiBundleCache;
22      private final File frameworkBundleCache;
23      private final File transformedPluginCache;
24      private final Logger log = LoggerFactory.getLogger(DefaultOsgiPersistentCache.class);
25  
26      /**
27       * Constructs a cache, using the passed file as the base directory for cache subdirectories
28       * @param baseDir The base directory
29       */
30      public DefaultOsgiPersistentCache(final File baseDir)
31      {
32          Validate.notNull(baseDir, "The base directory for OSGi caches cannot be null");
33          Validate.isTrue(baseDir.exists(), "The base directory for OSGi persistent caches should exist");
34          osgiBundleCache = new File(baseDir, "felix");
35          frameworkBundleCache = new File(baseDir, "framework-bundles");
36          transformedPluginCache = new File(baseDir, "transformed-plugins");
37          validate(null);
38      }
39  
40      /**
41       * Constructor added in the 2.2.0 beta timeframe, but was made redundant later.  Application version is not used.
42       * @deprecated
43       */
44      @Deprecated
45      public DefaultOsgiPersistentCache(final File baseDir, final String applicationVersion)
46      {
47          this(baseDir);
48      }
49  
50      public File getFrameworkBundleCache()
51      {
52          return frameworkBundleCache;
53      }
54  
55      public File getOsgiBundleCache()
56      {
57          return osgiBundleCache;
58      }
59  
60      public File getTransformedPluginCache()
61      {
62          return transformedPluginCache;
63      }
64  
65      public void clear() throws OsgiContainerException
66      {
67          try
68          {
69              FileUtils.cleanDirectory(frameworkBundleCache);
70              FileUtils.cleanDirectory(osgiBundleCache);
71              FileUtils.cleanDirectory(transformedPluginCache);
72          }
73          catch (final IOException e)
74          {
75              throw new OsgiContainerException("Unable to clear OSGi caches", e);
76          }
77      }
78  
79      public void validate(final String cacheValidationKey)
80      {
81          ensureDirectoryExists(frameworkBundleCache);
82          ensureDirectoryExists(osgiBundleCache);
83          ensureDirectoryExists(transformedPluginCache);
84  
85          try
86          {
87              FileUtils.cleanDirectory(osgiBundleCache);
88          }
89          catch (final IOException e)
90          {
91              throw new OsgiContainerException("Unable to clean the cache directory: " + osgiBundleCache, e);
92          }
93  
94          if (cacheValidationKey != null)
95          {
96              final String newHash = String.valueOf(cacheValidationKey.hashCode());
97              final File versionFile = new File(transformedPluginCache, "cache.key");
98              if (versionFile.exists())
99              {
100                 String oldVersion = null;
101                 try
102                 {
103                     oldVersion = FileUtils.readFileToString(versionFile);
104                 }
105                 catch (final IOException e)
106                 {
107                     log.debug("Unable to read cache key file", e);
108                 }
109                 if (!newHash.equals(oldVersion))
110                 {
111                     log.info("Application upgrade detected, clearing OSGi cache directories");
112                     clear();
113                 }
114                 else
115                 {
116                     return;
117                 }
118             }
119 
120             try
121             {
122                 FileUtils.writeStringToFile(versionFile, newHash);
123             }
124             catch (final IOException e)
125             {
126                 log.warn("Unable to write cache key file, so will be unable to detect upgrades", e);
127             }
128         }
129     }
130 
131     private void ensureDirectoryExists(final File dir)
132     {
133         if (dir.exists() && !dir.isDirectory())
134         {
135             throw new IllegalArgumentException("'"+dir+"' is not a directory");
136         }
137 
138         if (!dir.exists() && !dir.mkdir())
139         {
140             throw new IllegalArgumentException("Directory '"+dir+"' cannot be created");
141         }
142     }
143 }