View Javadoc

1   package com.atlassian.plugin.osgi.container.impl;
2   
3   import com.atlassian.plugin.osgi.container.OsgiContainerException;
4   import com.atlassian.plugin.osgi.container.OsgiPersistentCache;
5   
6   import org.apache.commons.io.FileUtils;
7   import org.apache.commons.lang.Validate;
8   import org.slf4j.LoggerFactory;
9   import org.slf4j.Logger;
10  
11  import java.io.File;
12  import java.io.IOException;
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 File versionFile = new File(transformedPluginCache, "cache.key");
97              if (versionFile.exists())
98              {
99                  String oldVersion = null;
100                 try
101                 {
102                     oldVersion = FileUtils.readFileToString(versionFile);
103                 }
104                 catch (final IOException e)
105                 {
106                     log.debug("Unable to read cache key file", e);
107                 }
108                 if (!cacheValidationKey.equals(oldVersion))
109                 {
110                     log.info("Application upgrade detected, clearing OSGi cache directories");
111                     clear();
112                 }
113                 else
114                 {
115                     return;
116                 }
117             }
118 
119             try
120             {
121                 FileUtils.writeStringToFile(versionFile, cacheValidationKey);
122             }
123             catch (final IOException e)
124             {
125                 log.warn("Unable to write cache key file, so will be unable to detect upgrades", e);
126             }
127         }
128     }
129 
130     private void ensureDirectoryExists(final File dir)
131     {
132         if (dir.exists() && !dir.isDirectory())
133         {
134             throw new IllegalArgumentException("'"+dir+"' is not a directory");
135         }
136 
137         if (!dir.exists() && !dir.mkdir())
138         {
139             throw new IllegalArgumentException("Directory '"+dir+"' cannot be created");
140         }
141     }
142 }