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
16
17
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
28
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
42
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 }