Search in sources :

Example 11 with PatchData

use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.

the class PatchServiceImplTest method bundleUpdatesInPatch.

@Test
@SuppressWarnings("unchecked")
public void bundleUpdatesInPatch() throws Exception {
    BundleContext context = mock(BundleContext.class);
    Bundle bundle0 = mock(Bundle.class);
    when(bundle0.getBundleContext()).thenReturn(context);
    when(context.getProperty("karaf.home")).thenReturn("target/bundleUpdatesInPatch");
    when(context.getProperty("karaf.base")).thenReturn("target/bundleUpdatesInPatch");
    when(context.getProperty("karaf.data")).thenReturn("target/bundleUpdatesInPatch/data");
    when(context.getProperty("karaf.etc")).thenReturn("target/bundleUpdatesInPatch/etc");
    when(context.getProperty("karaf.name")).thenReturn("root");
    when(context.getProperty("karaf.instances")).thenReturn("instances");
    when(context.getProperty("karaf.default.repository")).thenReturn("system");
    when(context.getProperty("fuse.patch.location")).thenReturn(null);
    when(context.getBundle(0)).thenReturn(bundle0);
    PatchServiceImpl service = new PatchServiceImpl();
    Method m = service.getClass().getDeclaredMethod("bundleUpdatesInPatch", Patch.class, Bundle[].class, Map.class, PatchServiceImpl.BundleVersionHistory.class, Map.class, PatchKind.class, Map.class, List.class);
    m.setAccessible(true);
    Field f = service.getClass().getDeclaredField("helper");
    f.setAccessible(true);
    f.set(service, new OSGiPatchHelper(new File("target/bundleUpdatesInPatch"), context) {

        @Override
        public String[] getBundleIdentity(String url) throws IOException {
            Artifact a = Utils.mvnurlToArtifact(url, false);
            return a == null ? null : new String[] { a.getArtifactId(), a.getVersion() };
        }
    });
    PatchData pd = new PatchData("patch-x");
    // for these two, bundle.getLocation() will return matching location
    pd.getBundles().add("mvn:io.fabric8/pax-romana/1.0.1");
    pd.getBundles().add("mvn:io.fabric8/pax-hellenica/1.0.1/jar");
    // for these two, bundle.getLocation() will return non-matching location
    pd.getBundles().add("mvn:io.fabric8/pax-bohemia/1.0.1");
    pd.getBundles().add("mvn:io.fabric8/pax-pomerania/1.0.1/jar");
    // for these two, bundle.getLocation() will return matching location
    pd.getBundles().add("mvn:io.fabric8/pax-avaria/1.0.1/jar/uber");
    pd.getBundles().add("mvn:io.fabric8/pax-mazovia/1.0.1//uber");
    // for these two, bundle.getLocation() will return non-matching location
    pd.getBundles().add("mvn:io.fabric8/pax-novgorod/1.0.1/jar/uber");
    pd.getBundles().add("mvn:io.fabric8/pax-castile/1.0.1//uber");
    f = pd.getClass().getDeclaredField("versionRanges");
    f.setAccessible(true);
    f.set(pd, new HashMap<>());
    Patch patch = new Patch(pd, null);
    Bundle[] bundles = new Bundle[8];
    bundles[0] = bundle("mvn:io.fabric8/pax-romana/1.0.0");
    bundles[1] = bundle("mvn:io.fabric8/pax-hellenica/1.0.0/jar");
    bundles[2] = bundle("mvn:io.fabric8/pax-bohemia/1.0.0/jar");
    bundles[3] = bundle("mvn:io.fabric8/pax-pomerania/1.0.0");
    bundles[4] = bundle("mvn:io.fabric8/pax-avaria/1.0.0/jar/uber");
    bundles[5] = bundle("mvn:io.fabric8/pax-mazovia/1.0.0//uber");
    bundles[6] = bundle("mvn:io.fabric8/pax-novgorod/1.0.0//uber");
    bundles[7] = bundle("mvn:io.fabric8/pax-castile/1.0.0/jar/uber");
    Object _list = m.invoke(service, patch, bundles, new HashMap<>(), new PatchServiceImpl.BundleVersionHistory(new HashMap<String, Patch>()), new HashMap<>(), PatchKind.NON_ROLLUP, new HashMap<>(), null);
    List<BundleUpdate> list = (List<BundleUpdate>) _list;
    assertThat(list.size(), equalTo(8));
    assertThat(list.get(0).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-romana/1.0.0"));
    assertThat(list.get(1).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-hellenica/1.0.0/jar"));
    assertThat(list.get(2).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-bohemia/1.0.0/jar"));
    assertThat(list.get(3).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-pomerania/1.0.0"));
    assertThat(list.get(4).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-avaria/1.0.0/jar/uber"));
    assertThat(list.get(5).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-mazovia/1.0.0//uber"));
    assertThat(list.get(6).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-novgorod/1.0.0//uber"));
    assertThat(list.get(7).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-castile/1.0.0/jar/uber"));
    assertThat(list.get(0).getNewLocation(), equalTo("mvn:io.fabric8/pax-romana/1.0.1"));
    assertThat(list.get(1).getNewLocation(), equalTo("mvn:io.fabric8/pax-hellenica/1.0.1/jar"));
    assertThat(list.get(2).getNewLocation(), equalTo("mvn:io.fabric8/pax-bohemia/1.0.1"));
    assertThat(list.get(3).getNewLocation(), equalTo("mvn:io.fabric8/pax-pomerania/1.0.1/jar"));
    assertThat(list.get(4).getNewLocation(), equalTo("mvn:io.fabric8/pax-avaria/1.0.1/jar/uber"));
    assertThat(list.get(5).getNewLocation(), equalTo("mvn:io.fabric8/pax-mazovia/1.0.1//uber"));
    assertThat(list.get(6).getNewLocation(), equalTo("mvn:io.fabric8/pax-novgorod/1.0.1/jar/uber"));
    assertThat(list.get(7).getNewLocation(), equalTo("mvn:io.fabric8/pax-castile/1.0.1//uber"));
    // ---
    Repository repository = mock(Repository.class);
    File tmp = new File("target/bundleUpdatesInPatch/" + UUID.randomUUID().toString());
    tmp.mkdirs();
    File startupProperties = new File(tmp, "etc/startup.properties");
    FileUtils.copyFile(new File("src/test/resources/uber-startup.properties"), startupProperties);
    when(repository.getWorkTree()).thenReturn(tmp);
    Git fork = mock(Git.class);
    when(fork.getRepository()).thenReturn(repository);
    GitPatchManagementServiceImpl gitPatchManagementService = new GitPatchManagementServiceImpl(context);
    m = gitPatchManagementService.getClass().getDeclaredMethod("updateFileReferences", Git.class, PatchData.class, List.class);
    m.setAccessible(true);
    m.invoke(gitPatchManagementService, fork, pd, list);
    try (FileReader reader = new FileReader(startupProperties)) {
        Properties startup = new Properties();
        startup.load(reader);
        assertTrue(startup.containsKey("io/fabric8/pax-romana/1.0.1/pax-romana-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-hellenica/1.0.1/pax-hellenica-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-bohemia/1.0.1/pax-bohemia-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-pomerania/1.0.1/pax-pomerania-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-avaria/1.0.1/pax-avaria-1.0.1-uber.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-mazovia/1.0.1/pax-mazovia-1.0.1-uber.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-novgorod/1.0.1/pax-novgorod-1.0.1-uber.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-castile/1.0.1/pax-castile-1.0.1-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-romana/1.0.0/pax-romana-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-hellenica/1.0.0/pax-hellenica-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-bohemia/1.0.0/pax-bohemia-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-pomerania/1.0.0/pax-pomerania-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-avaria/1.0.0/pax-avaria-1.0.0-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-mazovia/1.0.0/pax-mazovia-1.0.0-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-novgorod/1.0.0/pax-novgorod-1.0.0-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-castile/1.0.0/pax-castile-1.0.0-uber.jar"));
    }
}
Also used : HashMap(java.util.HashMap) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Properties(java.util.Properties) Field(java.lang.reflect.Field) List(java.util.List) LinkedList(java.util.LinkedList) FileReader(java.io.FileReader) BundleUpdate(org.jboss.fuse.patch.management.BundleUpdate) PatchData(org.jboss.fuse.patch.management.PatchData) Bundle(org.osgi.framework.Bundle) Method(java.lang.reflect.Method) IOException(java.io.IOException) Artifact(org.jboss.fuse.patch.management.Artifact) GitPatchRepository(org.jboss.fuse.patch.management.impl.GitPatchRepository) Repository(org.eclipse.jgit.lib.Repository) Git(org.eclipse.jgit.api.Git) GitPatchManagementServiceImpl(org.jboss.fuse.patch.management.impl.GitPatchManagementServiceImpl) JarFile(java.util.jar.JarFile) File(java.io.File) Patch(org.jboss.fuse.patch.management.Patch) BundleContext(org.osgi.framework.BundleContext) Test(org.junit.Test)

Example 12 with PatchData

use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.

the class PatchServiceImplTest method testVersionHistory.

@Test
public void testVersionHistory() {
    // the same bundle has been patched twice
    Patch patch1 = new Patch(new PatchData("patch1", "First patch", null, null, null, null, null), null);
    patch1.setResult(new PatchResult(patch1.getPatchData(), true, System.currentTimeMillis(), new LinkedList<org.jboss.fuse.patch.management.BundleUpdate>(), null, null));
    patch1.getResult().getBundleUpdates().add(new BundleUpdate("my-bsn", "1.1.0", "mvn:groupId/my-bsn/1.1.0", "1.0.0", "mvn:groupId/my-bsn/1.0.0"));
    Patch patch2 = new Patch(new PatchData("patch2", "Second patch", null, null, null, null, null), null);
    patch2.setResult(new PatchResult(patch1.getPatchData(), true, System.currentTimeMillis(), new LinkedList<org.jboss.fuse.patch.management.BundleUpdate>(), null, null));
    patch2.getResult().getBundleUpdates().add(new BundleUpdate("my-bsn;directive1=true", "1.2.0", "mvn:groupId/my-bsn/1.2.0", "1.1.0", "mvn:groupId/my-bsn/1.1.0"));
    Map<String, Patch> patches = new HashMap<String, Patch>();
    patches.put("patch1", patch1);
    patches.put("patch2", patch2);
    // the version history should return the correct URL, even when bundle.getLocation() does not
    PatchServiceImpl.BundleVersionHistory history = new PatchServiceImpl.BundleVersionHistory(patches);
    assertEquals("Should return version from patch result instead of the original location", "mvn:groupId/my-bsn/1.2.0", history.getLocation(createMockBundle("my-bsn", "1.2.0", "mvn:groupId/my-bsn/1.0.0")));
    assertEquals("Should return version from patch result instead of the original location", "mvn:groupId/my-bsn/1.1.0", history.getLocation(createMockBundle("my-bsn", "1.1.0", "mvn:groupId/my-bsn/1.0.0")));
    assertEquals("Should return original bundle location if no maching version is found in the history", "mvn:groupId/my-bsn/1.0.0", history.getLocation(createMockBundle("my-bsn", "1.0.0", "mvn:groupId/my-bsn/1.0.0")));
    assertEquals("Should return original bundle location if no maching version is found in the history", "mvn:groupId/my-bsn/0.9.0", history.getLocation(createMockBundle("my-bsn", "0.9.0", "mvn:groupId/my-bsn/0.9.0")));
}
Also used : PatchData(org.jboss.fuse.patch.management.PatchData) HashMap(java.util.HashMap) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) LinkedList(java.util.LinkedList) PatchResult(org.jboss.fuse.patch.management.PatchResult) Patch(org.jboss.fuse.patch.management.Patch) BundleUpdate(org.jboss.fuse.patch.management.BundleUpdate) Test(org.junit.Test)

Example 13 with PatchData

use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.

the class PatchServiceImplTest method testLoadWithRanges.

@Test
public void testLoadWithRanges() throws IOException {
    PatchServiceImpl service = createMockServiceImpl();
    PatchData pd = PatchData.load(getClass().getClassLoader().getResourceAsStream("test2.patch"));
    assertEquals(2, pd.getBundles().size());
    assertEquals("[1.0.0,2.0.0)", pd.getVersionRange("mvn:io.fabric8.test/test1/1.0.0"));
    assertNull(pd.getVersionRange("mvn:io.fabric8.test/test2/1.0.0"));
    assertTrue(pd.getRequirements().isEmpty());
}
Also used : PatchData(org.jboss.fuse.patch.management.PatchData) Test(org.junit.Test)

Example 14 with PatchData

use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.

the class FileBackupTest method backupSomeDataFiles.

@Test
public void backupSomeDataFiles() throws IOException {
    PatchData patchData = new PatchData("my-patch");
    patchData.setPatchLocation(new File(karafHome, "patches"));
    PatchResult result = new PatchResult(patchData);
    // updates installed bundle, has data dir
    BundleUpdate b3 = new BundleUpdate("com.irrelevant.services", "1.2", "file:/dev/null", "1.1.0", "file:/dev/random");
    // updates installed bundle, has data dir, but special case
    BundleUpdate b4 = new BundleUpdate("org.apache.karaf.features.core", "1.3", "file:/dev/null", "1.2.1", "file:/dev/random");
    // reinstalled bundle, has data dir
    BundleUpdate b5 = new BundleUpdate("com.irrelevant.iot", null, null, "1.2.5", "file:/dev/random");
    // reinstalled bundle, no data dir
    BundleUpdate b6 = new BundleUpdate("com.irrelevant.space", null, null, "1.1.0", "file:/dev/random");
    // update, but not for installed bundle
    BundleUpdate b7 = new BundleUpdate("com.irrelevant.the.final.frontier", "1.5", "file:/dev/null", "1.1.3", "file:/dev/random");
    result.getBundleUpdates().add(b3);
    result.getBundleUpdates().add(b4);
    result.getBundleUpdates().add(b5);
    result.getBundleUpdates().add(b6);
    result.getBundleUpdates().add(b7);
    new FileBackupService(sys).backupDataFiles(result, Pending.ROLLUP_INSTALLATION);
    Properties props = new Properties();
    props.load(new FileInputStream(new File(karafHome, "patches/my-patch.datafiles/backup-install.properties")));
    assertThat(props.getProperty("com.irrelevant.services$$1.1.0"), equalTo("com.irrelevant.services$$1.1.0"));
    assertThat(props.getProperty("com.irrelevant.services$$1.2"), equalTo("com.irrelevant.services$$1.1.0"));
    assertThat(props.getProperty("com.irrelevant.iot$$1.2.5"), equalTo("com.irrelevant.iot$$1.2.5"));
    assertThat(props.stringPropertyNames().size(), equalTo(3));
    assertTrue(new File(karafHome, "patches/my-patch.datafiles/install/com.irrelevant.services$$1.1.0/data/x").isDirectory());
    assertTrue(new File(karafHome, "patches/my-patch.datafiles/install/com.irrelevant.iot$$1.2.5/data/z").isDirectory());
    assertFalse(new File(karafHome, "patches/my-patch.datafiles/install/com.irrelevant.the.final.frontier$$1.5").isDirectory());
}
Also used : PatchData(org.jboss.fuse.patch.management.PatchData) PatchResult(org.jboss.fuse.patch.management.PatchResult) Properties(java.util.Properties) File(java.io.File) BundleUpdate(org.jboss.fuse.patch.management.BundleUpdate) FileInputStream(java.io.FileInputStream) Test(org.junit.Test)

Example 15 with PatchData

use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.

the class DiffUtils method generateDiffReport.

/**
 * <p>Having four commits, generate single, HTML report about all modified files</p>
 * <p>Please excuse inline html code.</p>
 * @param patch
 * @param git
 * @param conflicts
 * @param base
 * @param ours
 * @param theirs
 * @param resolved
 * @param result
 */
public static void generateDiffReport(Patch patch, PatchResult patchResult, Git git, Set<String> conflicts, RevCommit base, RevCommit ours, RevCommit theirs, RevCommit resolved, Writer result) throws IOException {
    ObjectReader reader = git.getRepository().newObjectReader();
    CanonicalTreeParser ctpBase = new CanonicalTreeParser();
    CanonicalTreeParser ctpOurs = new CanonicalTreeParser();
    CanonicalTreeParser ctpTheirs = new CanonicalTreeParser();
    CanonicalTreeParser ctpResolved = new CanonicalTreeParser();
    ctpBase.reset(reader, base.getTree());
    ctpOurs.reset(reader, ours.getTree());
    ctpTheirs.reset(reader, theirs.getTree());
    ctpResolved.reset(reader, resolved.getTree());
    // this map will contain 3 diffs for each file/path:
    // 0 - diff between base and "ours" ("ours" depends on patch kind and it's really "ours" in P-Patch,
    // because patch change is cherry-picked on top of custom change. In R-Patch, custom changes come after
    // patch, so they're called "theirs" in diff/git terminology)
    // 1 - diff between base and "theirs" (see above)
    // 2 - diff between base and resolved, effective and final state of history
    Map<String, DiffEntry[]> report = new LinkedHashMap<>();
    // 1. base -> ours
    TreeWalk walk = new TreeWalk(reader);
    walk.addTree(ctpBase);
    walk.addTree(ctpOurs);
    walk.setRecursive(true);
    List<DiffEntry> diffs = DiffEntry.scan(walk);
    diffs.forEach(de -> collect(report, de, 0));
    // 2. base -> theirs
    walk.reset();
    ctpBase.reset(reader, base.getTree());
    walk.addTree(ctpBase);
    walk.addTree(ctpTheirs);
    walk.setRecursive(true);
    diffs = DiffEntry.scan(walk);
    diffs.forEach(de -> collect(report, de, 1));
    // 3. base -> resolved
    walk.reset();
    ctpBase.reset(reader, base.getTree());
    walk.addTree(ctpBase);
    walk.addTree(ctpResolved);
    walk.setRecursive(true);
    diffs = DiffEntry.scan(walk);
    diffs.forEach(de -> collect(report, de, 2));
    // report generation
    PatchData pd = patchResult.getPatchData();
    result.write(reportHeader.replace("@PATCH_ID@", pd.getId()));
    PatchReport pr = patchResult.getReport();
    result.write("<table class=\"summary\">\n" + "        <tr>\n" + "            <td class=\"f\">Patch ID:</td><td>" + pr.getId() + "</td>\n" + "        </tr>\n" + "        <tr>\n" + "            <td class=\"f\">Patch type:</td><td>" + (pr.isRollup() ? "rollup" : "non-rollup") + "</td>\n" + "        </tr>\n" + "        <tr>\n" + "            <td class=\"f\">Installation date:</td><td>" + DATE.format(pr.getTimestamp()) + "</td>\n" + "        </tr>\n" + "        <tr>\n" + "            <td class=\"f\">Bundles updated</td><td>" + pr.getUpdatedBundles() + "</td>\n" + "        </tr>\n" + "        <tr>\n" + "            <td class=\"f\">Features updated</td><td>" + pr.getUpdatedFeatures() + "</td>\n" + "        </tr>\n" + "        <tr>\n" + "            <td class=\"f\">Features overriden</td><td>" + pr.getOverridenFeatures() + "</td>\n" + "        </tr>\n" + "        <tr>\n" + "            <td class=\"f\">File conflicts</td><td>" + conflicts.size() + "</td>\n" + "        </tr>\n" + "    </table>\n" + "</div>\n");
    if (conflicts.size() > 0) {
        result.write("<h1 class=\"header\">\n" + "  <div>Conflicting files</div>\n" + "</h1>\n");
    }
    for (Map.Entry<String, DiffEntry[]> e : report.entrySet()) {
        if (!conflicts.contains(e.getKey())) {
            // we don't care about diffs that aren't really conflicts
            continue;
        }
        result.write(fileHeader1);
        result.write(e.getKey());
        result.write(fileHeader2);
        // we have max 3 entries (not all entries may be present
        result.write("<td class=\"side\">\n" + "          <div class=\"header\">Custom version</div>\n" + "          <div class=\"content" + (e.getValue()[0] != null ? "" : " empty") + "\">");
        if (e.getValue()[0] != null) {
            // custom change
            diff(git, reader, e.getValue()[0], result);
        } else {
            result.write("No change");
        }
        result.write("</div>\n" + "        </td>");
        result.write("<td class=\"side\">\n" + "          <div class=\"header\">Patch</div>\n" + "          <div class=\"content" + (e.getValue()[1] != null ? "" : " empty") + "\">");
        if (e.getValue()[1] != null) {
            // patch change
            diff(git, reader, e.getValue()[1], result);
        } else {
            result.write("No change");
        }
        result.write("</div>\n" + "        </td>");
        result.write("<td class=\"side\">\n" + "          <div class=\"header\">Final version</div>\n" + "          <div class=\"content" + (e.getValue()[2] != null ? "" : " empty") + "\">");
        if (e.getValue()[2] != null) {
            // effective change - should always be available
            // or maybe not when both patch and user removed the file?
            diff(git, reader, e.getValue()[2], result);
        } else {
            result.write("No change");
        }
        result.write("</div>\n" + "        </td>");
        result.write(fileFooter);
    }
    result.write(reportFooter);
}
Also used : PatchData(org.jboss.fuse.patch.management.PatchData) PatchReport(org.jboss.fuse.patch.management.PatchReport) ObjectReader(org.eclipse.jgit.lib.ObjectReader) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) CanonicalTreeParser(org.eclipse.jgit.treewalk.CanonicalTreeParser) LinkedHashMap(java.util.LinkedHashMap) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Aggregations

PatchData (org.jboss.fuse.patch.management.PatchData)16 Patch (org.jboss.fuse.patch.management.Patch)9 File (java.io.File)8 Test (org.junit.Test)8 IOException (java.io.IOException)6 LinkedList (java.util.LinkedList)6 PatchResult (org.jboss.fuse.patch.management.PatchResult)6 FileInputStream (java.io.FileInputStream)5 PatchException (org.jboss.fuse.patch.management.PatchException)5 ZipFile (org.apache.commons.compress.archivers.zip.ZipFile)4 BundleUpdate (org.jboss.fuse.patch.management.BundleUpdate)4 GitPatchManagementServiceImpl (org.jboss.fuse.patch.management.impl.GitPatchManagementServiceImpl)4 Bundle (org.osgi.framework.Bundle)4 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 Properties (java.util.Properties)3 Artifact (org.jboss.fuse.patch.management.Artifact)3 PatchDetailsRequest (org.jboss.fuse.patch.management.PatchDetailsRequest)3 Version (org.osgi.framework.Version)3 FileWriter (java.io.FileWriter)2