ReleaseInfoPlugin.java revision 15216:6c827500e345
1/*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package jdk.tools.jlink.internal.plugins;
26
27import java.io.ByteArrayOutputStream;
28import java.io.FileInputStream;
29import java.io.IOException;
30import java.io.UncheckedIOException;
31import java.lang.module.ModuleDescriptor;
32import java.util.EnumSet;
33import java.util.HashMap;
34import java.util.Map;
35import java.util.Optional;
36import java.util.Properties;
37import java.util.Set;
38import java.util.function.Function;
39import jdk.tools.jlink.internal.Utils;
40import jdk.tools.jlink.plugin.ResourcePool;
41import jdk.tools.jlink.plugin.ResourcePoolBuilder;
42import jdk.tools.jlink.plugin.ResourcePoolEntry;
43import jdk.tools.jlink.plugin.ResourcePoolModule;
44import jdk.tools.jlink.plugin.Plugin.Category;
45import jdk.tools.jlink.plugin.Plugin.State;
46import jdk.tools.jlink.plugin.Plugin;
47
48/**
49 * This plugin adds/deletes information for 'release' file.
50 */
51public final class ReleaseInfoPlugin implements Plugin {
52    // option name
53    public static final String NAME = "release-info";
54    public static final String KEYS = "keys";
55    private final Map<String, String> release = new HashMap<>();
56
57    @Override
58    public Category getType() {
59        return Category.METAINFO_ADDER;
60    }
61
62    @Override
63    public String getName() {
64        return NAME;
65    }
66
67    @Override
68    public String getDescription() {
69        return PluginsResourceBundle.getDescription(NAME);
70    }
71
72    @Override
73    public Set<State> getState() {
74        return EnumSet.of(State.FUNCTIONAL);
75    }
76
77    @Override
78    public boolean hasArguments() {
79        return true;
80    }
81
82    @Override
83    public String getArgumentsDescription() {
84        return PluginsResourceBundle.getArgument(NAME);
85    }
86
87    @Override
88    public void configure(Map<String, String> config) {
89        String operation = config.get(NAME);
90        switch (operation) {
91            case "add": {
92                // leave it to open-ended! source, java_version, java_full_version
93                // can be passed via this option like:
94                //
95                //     --release-info add:build_type=fastdebug,source=openjdk,java_version=9
96                // and put whatever value that was passed in command line.
97
98                config.keySet().stream().
99                    filter(s -> !NAME.equals(s)).
100                    forEach(s -> release.put(s, config.get(s)));
101            }
102            break;
103
104            case "del": {
105                // --release-info del:keys=openjdk,java_version
106                Utils.parseList(config.get(KEYS)).stream().forEach((k) -> {
107                    release.remove(k);
108                });
109            }
110            break;
111
112            default: {
113                // --release-info <file>
114                Properties props = new Properties();
115                try (FileInputStream fis = new FileInputStream(operation)) {
116                    props.load(fis);
117                } catch (IOException exp) {
118                    throw new RuntimeException(exp);
119                }
120                props.forEach((k, v) -> release.put(k.toString(), v.toString()));
121            }
122            break;
123        }
124    }
125
126    @Override
127    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
128        in.transformAndCopy(Function.identity(), out);
129
130        // create a TOP level ResourcePoolEntry for "release" file.
131        out.add(ResourcePoolEntry.create("/java.base/release",
132            ResourcePoolEntry.Type.TOP, releaseFileContent()));
133        return out.build();
134    }
135
136    private byte[] releaseFileContent() {
137        Properties props = new Properties();
138        props.putAll(release);
139        ByteArrayOutputStream baos = new ByteArrayOutputStream();
140        try {
141            props.store(baos, "");
142            return baos.toByteArray();
143        } catch (IOException ex) {
144            throw new UncheckedIOException(ex);
145        }
146    }
147}
148