ctkPluginStorage_p.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #ifndef CTKPLUGINSTORAGE_P_H
  2. #define CTKPLUGINSTORAGE_P_H
  3. #include "ctkPluginFrameworkContext.h"
  4. #include "ctkPluginArchiveInterface_p.h"
  5. namespace ctk {
  6. class PluginStorage {
  7. private:
  8. /**
  9. * Plugin id sorted list of all active plugin archives.
  10. */
  11. QList<PluginArchiveInterface*> archives;
  12. /**
  13. * Framework handle.
  14. */
  15. PluginFrameworkContext* framework;
  16. public:
  17. /**
  18. * Create a container for all plugin data in this framework.
  19. * Try to restore all saved plugin archive state.
  20. *
  21. */
  22. PluginStorage(PluginFrameworkContext* framework)
  23. : framework(framework)
  24. {
  25. // See if we have a storage database
  26. bundlesDir = Util.getFileStorage(framework, "bs");
  27. if (bundlesDir == null) {
  28. throw new RuntimeException("No bundle storage area available!");
  29. }
  30. // Restore all saved bundles
  31. String [] list = bundlesDir.list();
  32. for (int i = 0; list != null & i < list.length; i++) {
  33. long id;
  34. try {
  35. id = Long.parseLong(list[i]);
  36. } catch (NumberFormatException e) {
  37. continue;
  38. }
  39. if (id == 0) {
  40. System.err.println("Saved bundle with illegal id 0 is ignored.");
  41. }
  42. int pos = find(id);
  43. if (pos < archives.size() && ((BundleArchive)archives.get(pos)).getBundleId() == id) {
  44. System.err.println("There are two bundle directories with id: " + id);
  45. break;
  46. }
  47. FileTree dir = new FileTree(bundlesDir, list[i]);
  48. if (dir.isDirectory()) {
  49. try {
  50. boolean bUninstalled = BundleArchiveImpl.isUninstalled(dir);
  51. if(bUninstalled) {
  52. // silently remove any bundle marked as uninstalled
  53. dir.delete();
  54. } else {
  55. BundleArchive ba = new BundleArchiveImpl(this, dir, id);
  56. archives.add(pos, ba);
  57. }
  58. if (id >= nextFreeId) {
  59. nextFreeId = id + 1;
  60. }
  61. } catch (Exception e) {
  62. dir.delete();
  63. System.err.println("Removed corrupt bundle dir (" + e.getMessage() + "): " + dir);
  64. }
  65. }
  66. }
  67. }
  68. /**
  69. * Insert bundle into persistent storage
  70. *
  71. * @param location Location of bundle.
  72. * @param is Inputstrem with bundle content.
  73. * @return Bundle archive object.
  74. */
  75. public BundleArchive insertBundleJar(String location, InputStream is)
  76. throws Exception
  77. {
  78. long id = nextFreeId++;
  79. FileTree dir = new FileTree(bundlesDir, String.valueOf(id));
  80. if (dir.exists()) {
  81. // remove any old garbage
  82. dir.delete();
  83. }
  84. dir.mkdir();
  85. try {
  86. BundleArchive ba = new BundleArchiveImpl(this, dir, is, location, id);
  87. archives.add(ba);
  88. return ba;
  89. } catch (Exception e) {
  90. dir.delete();
  91. throw e;
  92. }
  93. }
  94. /**
  95. * Insert a new jar file into persistent storagedata as an update
  96. * to an existing bundle archive. To commit this data a call to
  97. * <code>replaceBundleArchive</code> is needed.
  98. *
  99. * @param old BundleArchive to be replaced.
  100. * @param is Inputstrem with bundle content.
  101. * @return Bundle archive object.
  102. */
  103. public BundleArchive updateBundleArchive(BundleArchive old, InputStream is)
  104. throws Exception
  105. {
  106. return new BundleArchiveImpl((BundleArchiveImpl)old, is);
  107. }
  108. /**
  109. * Replace old bundle archive with a new updated bundle archive, that
  110. * was created with updateBundleArchive.
  111. *
  112. * @param oldBA BundleArchive to be replaced.
  113. * @param newBA Inputstrem with bundle content.
  114. * @return New bundle archive object.
  115. */
  116. public void replaceBundleArchive(BundleArchive oldBA, BundleArchive newBA)
  117. throws Exception
  118. {
  119. int pos;
  120. long id = oldBA.getBundleId();
  121. synchronized (archives) {
  122. pos = find(id);
  123. if (pos >= archives.size() || archives.get(pos) != oldBA) {
  124. throw new Exception("replaceBundleJar: Old bundle archive not found, pos=" + pos);
  125. }
  126. archives.set(pos, newBA);
  127. }
  128. }
  129. /**
  130. * Get all bundle archive objects.
  131. *
  132. * @return Private array of all BundleArchives.
  133. */
  134. public BundleArchive [] getAllBundleArchives() {
  135. synchronized (archives) {
  136. return (BundleArchive [])archives.toArray(new BundleArchive[archives.size()]);
  137. }
  138. }
  139. /**
  140. * Get all bundles to start at next launch of framework.
  141. * This list is sorted in increasing bundle id order.
  142. *
  143. * @return Private copy of a List with bundle id's.
  144. */
  145. public List getStartOnLaunchBundles() {
  146. ArrayList res = new ArrayList();
  147. for (Iterator i = archives.iterator(); i.hasNext(); ) {
  148. BundleArchive ba = (BundleArchive)i.next();
  149. if (ba.getAutostartSetting()!=-1) {
  150. res.add(ba.getBundleLocation());
  151. }
  152. }
  153. return res;
  154. }
  155. /**
  156. * Close bundle storage.
  157. *
  158. */
  159. public void close()
  160. {
  161. for (Iterator i = archives.iterator(); i.hasNext(); ) {
  162. BundleArchive ba = (BundleArchive) i.next();
  163. ba.close();
  164. i.remove();
  165. }
  166. framework = null;
  167. bundlesDir = null;
  168. }
  169. private:
  170. /**
  171. * Remove bundle archive from archives list.
  172. *
  173. * @param id Bundle archive id to find.
  174. * @return true if element was removed.
  175. */
  176. bool removeArchive(PluginArchiveInterface* ba) {
  177. synchronized (archives) {
  178. int pos = find(ba.getBundleId());
  179. if (pos < archives.size() && archives.get(pos) == ba) {
  180. archives.remove(pos);
  181. return true;
  182. } else {
  183. return false;
  184. }
  185. }
  186. }
  187. /**
  188. * Find posisition for BundleArchive with specified id
  189. *
  190. * @param id Bundle archive id to find.
  191. * @return String to write
  192. */
  193. int find(long id) {
  194. int lb = 0;
  195. int ub = archives.size() - 1;
  196. int x = 0;
  197. while (lb < ub) {
  198. x = (lb + ub) / 2;
  199. long xid = ((BundleArchive)archives.get(x)).getBundleId();
  200. if (id == xid) {
  201. return x;
  202. } else if (id < xid) {
  203. ub = x;
  204. } else {
  205. lb = x+1;
  206. }
  207. }
  208. if (lb < archives.size() && ((BundleArchive)archives.get(lb)).getBundleId() < id) {
  209. return lb + 1;
  210. }
  211. return lb;
  212. }
  213. };
  214. }
  215. #endif // CTKPLUGINSTORAGE_P_H