View Javadoc
1   package com.atlassian.plugin.osgi.container.felix;
2   
3   import com.atlassian.plugin.util.ClassLoaderUtils;
4   import com.google.common.base.Function;
5   import com.google.common.collect.ImmutableMap;
6   import com.google.common.collect.Maps;
7   import org.apache.commons.io.IOUtils;
8   import org.osgi.framework.Version;
9   import org.slf4j.Logger;
10  import org.slf4j.LoggerFactory;
11  import org.twdata.pkgscanner.DefaultOsgiVersionConverter;
12  import org.twdata.pkgscanner.ExportPackage;
13  
14  import java.io.IOException;
15  import java.io.InputStream;
16  import java.util.Map;
17  import java.util.Properties;
18  
19  import static org.apache.commons.lang3.StringUtils.defaultString;
20  
21  final class ExportBuilderUtils {
22      private static Logger LOG = LoggerFactory.getLogger(ExportBuilderUtils.class);
23      private static final DefaultOsgiVersionConverter converter = new DefaultOsgiVersionConverter();
24      private static final String EMPTY_OSGI_VERSION = Version.emptyVersion.toString();
25  
26      /**
27       * Not for instantiation.
28       */
29      private ExportBuilderUtils() {
30      }
31  
32      /**
33       * Convert version string into OSGi format.
34       */
35      private static final Function<String, String> CONVERT_VERSION = new Function<String, String>() {
36          public String apply(String from) {
37              if (from != null && (from.trim().length() > 0)) {
38                  return converter.getVersion(from);
39              } else {
40                  return EMPTY_OSGI_VERSION;
41              }
42          }
43      };
44  
45      /**
46       * Reads export file and return a map of package->version.
47       * Returned versions are in OSGi format which can be 0.0.0 if not specified in the file.
48       *
49       * @param exportFilePath the file path, never null.
50       * @return map of package->version, never null.
51       */
52      static Map<String, String> parseExportFile(String exportFilePath) {
53          Properties props = new Properties();
54          InputStream in = null;
55  
56          try {
57              in = ClassLoaderUtils.getResourceAsStream(exportFilePath, ExportBuilderUtils.class);
58              if (in == null) {
59                  LOG.warn("Unable to find properties for package export: " + exportFilePath);
60                  return ImmutableMap.of();
61              }
62              // this should automatically get rid of comment lines.
63              props.load(in);
64          } catch (IOException e) {
65              LOG.warn("Problem occurred while processing package export: " + exportFilePath, e);
66              return ImmutableMap.of();
67          } finally {
68              IOUtils.closeQuietly(in);
69          }
70  
71          // convert version strings to osgi format and return the resultant map.
72          // this Maps.transformValues returns a view backed by immutable map in this case so itself is already immutable.
73          return Maps.transformValues(Maps.fromProperties(props), CONVERT_VERSION);
74      }
75  
76      /**
77       * Copies all the entries from src into dest for the keys that don't already exist in dest.
78       */
79      static void copyUnlessExist(final Map<String, String> dest, final Map<String, String> src) {
80          dest.putAll(Maps.filterKeys(src, key -> !dest.containsKey(key)));
81      }
82  
83      /**
84       * Converts collection of ExportPackage into map of packageName->version.
85       */
86      static Map<String, String> toMap(Iterable<ExportPackage> exportPackages) {
87          ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
88          for (ExportPackage pkg : exportPackages) {
89              builder.put(pkg.getPackageName(), defaultString(pkg.getVersion(), EMPTY_OSGI_VERSION));
90          }
91          return builder.build();
92      }
93  }