Method: addBundlesToBundlesInfo(File[])

1:
2: package org.eclipse.virgo.nano.deployer.util;
3:
4: import java.io.File;
5: import java.io.IOException;
6: import java.net.URI;
7: import java.net.URISyntaxException;
8: import java.net.URL;
9: import java.util.HashMap;
10: import java.util.List;
11: import java.util.jar.Attributes;
12: import java.util.jar.JarFile;
13: import java.util.jar.Manifest;
14:
15: import org.eclipse.equinox.internal.simpleconfigurator.manipulator.SimpleConfiguratorManipulatorUtils;
16: import org.eclipse.equinox.internal.simpleconfigurator.utils.BundleInfo;
17: import org.eclipse.equinox.internal.simpleconfigurator.utils.SimpleConfiguratorUtils;
18: import org.eclipse.osgi.util.ManifestElement;
19: import org.eclipse.virgo.nano.deployer.SimpleDeployer;
20: import org.osgi.framework.Bundle;
21: import org.osgi.framework.BundleException;
22: import org.osgi.framework.Constants;
23:
24: /**
25: *
26: * Utility class that updates a bundles.info file.
27: *
28: * <strong>Concurrent Semantics</strong><br />
29: * Not thread-safe.
30: */
31: public class BundleInfosUpdater {
32:
33: private static final String UNKNOWN = "unknown";
34:
35: private static File bundlesInfoFile;
36:
37: private static File baseDir;
38:
39: private static HashMap<String, BundleInfo> toBeAddedInBundlesInfo;
40:
41: private static HashMap<String, BundleInfo> toBeRemovedFromBundlesInfo;
42:
43: public BundleInfosUpdater(URL bundlesInfoURL, File base) {
44: bundlesInfoFile = new File(bundlesInfoURL.getFile());
45: toBeAddedInBundlesInfo = new HashMap<String, BundleInfo>();
46: toBeRemovedFromBundlesInfo = new HashMap<String, BundleInfo>();
47: baseDir = base;
48: }
49:
50: public BundleInfosUpdater(File bundlesInfo, File base) {
51: bundlesInfoFile = bundlesInfo;
52: toBeAddedInBundlesInfo = new HashMap<String, BundleInfo>();
53: toBeRemovedFromBundlesInfo = new HashMap<String, BundleInfo>();
54: baseDir = base;
55: }
56:
57: public static void registerToBundlesInfo(Bundle bundle, String stagedRelativeLocation, boolean isFragment) throws URISyntaxException, IOException, BundleException {
58: String symbolicName = bundle.getSymbolicName();
59: addBundleToBundlesInfo(symbolicName == null ? UNKNOWN : symbolicName, new URI(stagedRelativeLocation),
60: bundle.getVersion().toString(), SimpleDeployer.HOT_DEPLOYED_ARTIFACTS_START_LEVEL, !isFragment);
61: updateBundleInfosRepository();
62: }
63:
64: public static void unregisterToBundlesInfo(Bundle bundle, String stagedRelativeLocation, boolean isFragment) throws IOException, BundleException, URISyntaxException {
65: String symbolicName = bundle.getSymbolicName();
66: removeBundleFromBundlesInfo(symbolicName == null ? UNKNOWN : symbolicName, new URI(stagedRelativeLocation),
67: bundle.getVersion().toString(), SimpleDeployer.HOT_DEPLOYED_ARTIFACTS_START_LEVEL, !isFragment);
68: updateBundleInfosRepository();
69: }
70:
71: // writes an array to a bundles.info file
72: public void addBundlesToBundlesInfo(File[] files) throws IOException, BundleException {
73:• for (File currFile : files) {
74: BundleInfo currBundleInfo = bundleFile2BundleInfo(currFile, 4, true);
75:• if (currBundleInfo != null) {
76: toBeAddedInBundlesInfo.put(getIdentifier(currBundleInfo), currBundleInfo);
77: }
78: }
79: }
80:
81: private static String getIdentifier(BundleInfo bundleInfo) {
82: return bundleInfo.getSymbolicName() + "=" + bundleInfo.getVersion();
83: }
84:
85: // writes a single bundle info to a bundles.info file
86: public void addBundleToBundlesInfo(File file, int startLevel, boolean autoStartFlag) throws IOException, BundleException {
87: BundleInfo bundleInfo = bundleFile2BundleInfo(file, startLevel, autoStartFlag);
88: if (bundleInfo != null) {
89: toBeAddedInBundlesInfo.put(getIdentifier(bundleInfo), bundleInfo);
90: }
91: }
92:
93: private static void addBundleToBundlesInfo(String bundleSymbolicName, URI url, String bundleVersion, int startLevel, boolean autoStartFlag)
94: throws IOException, BundleException {
95: try {
96: BundleInfo bundleInfo = createBundleInfo(bundleSymbolicName, bundleVersion, url, startLevel, autoStartFlag);
97: if (bundleInfo != null) {
98: toBeAddedInBundlesInfo.put(getIdentifier(bundleInfo), bundleInfo);
99: }
100: } catch (URISyntaxException ex) {
101: throw new IOException(ex.getCause());
102: }
103: }
104:
105: private static void removeBundleFromBundlesInfo(String bundleSymbolicName, URI url, String bundleVersion, int startLevel, boolean autoStartFlag)
106: throws IOException, BundleException {
107: try {
108: BundleInfo bundleInfo = createBundleInfo(bundleSymbolicName, bundleVersion, url, startLevel, autoStartFlag);
109: if (bundleInfo != null) {
110: toBeRemovedFromBundlesInfo.put(getIdentifier(bundleInfo), bundleInfo);
111: }
112: } catch (URISyntaxException ex) {
113: throw new IOException(ex.getCause());
114: }
115: }
116:
117: public boolean isAvailable() {
118: return bundlesInfoFile.exists();
119: }
120:
121: private static HashMap<String, BundleInfo> readBundleInfosInMap(List<BundleInfo> bundleInfos) {
122: HashMap<String, BundleInfo> infos = new HashMap<String, BundleInfo>();
123: for (BundleInfo bundleInfo : bundleInfos) {
124: infos.put(getIdentifier(bundleInfo), bundleInfo);
125: }
126: return infos;
127: }
128:
129: @SuppressWarnings("unchecked")
130:         private static void updateBundleInfosRepository() throws IOException {
131: List<BundleInfo> readConfiguration = SimpleConfiguratorUtils.readConfiguration(bundlesInfoFile.toURI().toURL(), baseDir == null ? null : baseDir.toURI());
132:                 HashMap<String, BundleInfo> currentBundleInfos = readBundleInfosInMap(readConfiguration);
133:
134: currentBundleInfos.putAll(toBeAddedInBundlesInfo);
135: toBeAddedInBundlesInfo.clear();
136:
137: for (String identifier : toBeRemovedFromBundlesInfo.keySet()) {
138: currentBundleInfos.remove(identifier);
139: }
140: toBeRemovedFromBundlesInfo.clear();
141:
142: if (bundlesInfoFile.exists()) {
143: String backupName = bundlesInfoFile.getName() + System.currentTimeMillis();
144: File backupFile = new File(bundlesInfoFile.getParentFile(), backupName);
145: if (!bundlesInfoFile.renameTo(backupFile)) {
146: throw new IOException("Fail to rename from (" + bundlesInfoFile + ") to (" + backupFile + ")");
147: }
148: }
149:
150: SimpleConfiguratorManipulatorUtils.writeConfiguration(currentBundleInfos.values().toArray(new BundleInfo[currentBundleInfos.size()]),
151: bundlesInfoFile);
152: }
153:
154: private static BundleInfo bundleFile2BundleInfo(File file, int startLevel, boolean autoStartFlag) throws IOException, BundleException {
155: try {
156: JarFile jarFile = new JarFile(file);
157: Manifest manifest = jarFile.getManifest();
158: if (manifest != null) {
159: Attributes mainAttributes = manifest.getMainAttributes();
160: String symbName = mainAttributes.getValue(Constants.BUNDLE_SYMBOLICNAME);
161: if (symbName != null) {
162: ManifestElement[] symbNameHeader = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, symbName);
163: return createBundleInfo(symbNameHeader[0].getValue(), mainAttributes.getValue(Constants.BUNDLE_VERSION), file.toURI(),
164: startLevel, autoStartFlag);
165: }
166: }
167: return null;
168: } catch (URISyntaxException ex) {
169: throw new IOException(ex.getCause());
170: }
171: }
172:
173: private static BundleInfo createBundleInfo(String symbName, String bundleVersion, URI uri, int startLevel, boolean autoStart)
174: throws URISyntaxException {
175: return new BundleInfo(symbName, bundleVersion, uri, startLevel, autoStart);
176: }
177: }