+ /**
+ * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the root.
+ *
+ * @param bundle
+ * @return transferable graph, or <tt>null</tt> if there is no graph in the bundle.
+ * @throws IOException
+ */
+ private static GraphBundleEx tryGetOnDemandGraph(Bundle bundle, URL url) throws IOException {
+ try {
+ Integer cachedHash = readCachedHash(url);
+ if (cachedHash == null) {
+ LOGGER.info("No cached hash for " + bundle);
+ return null;
+ }
+
+ Supplier<TransferableGraph1> graphSource = () -> {
+ try {
+ return readTG(url);
+ } catch (Exception e) {
+ throw new RuntimeException("Problem loading graph.tg from bundle " + bundle.getSymbolicName(), e);
+ } catch (Error e) {
+ LOGGER.error("Serious problem loading graph.tg from bundle " + bundle.getSymbolicName(), e);
+ throw e;
+ }
+ };
+
+ String id = bundle.getSymbolicName();
+
+ return new GraphBundleEx(
+ getBundleName(bundle, id),
+ graphSource,
+ cachedHash,
+ new VersionedId(id, toP2Version(bundle)),
+ isImmutable(bundle));
+ } catch (Exception e) {
+ throw new IOException("Problem loading graph.tg from bundle " + bundle.getSymbolicName(), e);
+ }
+ }
+
+ private static TransferableGraph1 readTG(URL url) throws Exception {
+ try (InputStream is = url.openStream()) {
+ return TransferableGraphFileReader.read(is);
+ }
+ }
+
+ private static DataContainer readHeader(URL url) throws IOException {
+ try (InputStream is = url.openStream()) {
+ return DataContainers.readHeader(new DataInputStream(new BufferedInputStream(is, 1 << 14)));
+ }
+ }
+
+ private static Integer readCachedHash(URL url) throws IOException, AdaptException {
+ DataContainer header = readHeader(url);
+ Variant hashCode = header.metadata.get(Extensions.CACHED_HASHCODE);
+ return hashCode != null ? (Integer) hashCode.getValue(Bindings.INTEGER) : null;
+ }
+
+ private static Version toP2Version(Bundle bundle) {
+ org.osgi.framework.Version osgiVersion = bundle.getVersion();
+ return Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro(), osgiVersion.getQualifier());
+ }
+
+ private static String getBundleName(Bundle bundle, String id) {
+ String name = (String) bundle.getHeaders().get("Bundle-Name");
+ return name != null ? name : id;
+ }
+
+ private static boolean isImmutable(Bundle bundle) {
+ String immutable = (String) bundle.getHeaders().get("Immutable");
+ return immutable != null ? "true".equals(immutable) : true;
+ }
+