PrevisitorTest.java revision 13901:b2a69d66dc65
1219820Sjeff/*
2219820Sjeff * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3219820Sjeff * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4219820Sjeff *
5219820Sjeff * This code is free software; you can redistribute it and/or modify it
6219820Sjeff * under the terms of the GNU General Public License version 2 only, as
7219820Sjeff * published by the Free Software Foundation.
8219820Sjeff *
9219820Sjeff * This code is distributed in the hope that it will be useful, but WITHOUT
10219820Sjeff * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11219820Sjeff * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12219820Sjeff * version 2 for more details (a copy is included in the LICENSE file that
13219820Sjeff * accompanied this code).
14219820Sjeff *
15219820Sjeff * You should have received a copy of the GNU General Public License version
16219820Sjeff * 2 along with this work; if not, write to the Free Software Foundation,
17219820Sjeff * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18219820Sjeff *
19219820Sjeff * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20219820Sjeff * or visit www.oracle.com if you need additional information or have any
21219820Sjeff * questions.
22219820Sjeff */
23219820Sjeff
24219820Sjeff /*
25219820Sjeff * @test
26219820Sjeff * @summary Test previsitor
27219820Sjeff * @author Andrei Eremeev
28219820Sjeff * @modules jdk.jlink/jdk.tools.jlink.internal
29219820Sjeff * @run main/othervm PrevisitorTest
30219820Sjeff */
31219820Sjeffimport java.nio.ByteOrder;
32219820Sjeffimport java.util.ArrayList;
33219820Sjeffimport java.util.Collection;
34219820Sjeffimport java.util.Collections;
35219820Sjeffimport java.util.HashMap;
36219820Sjeffimport java.util.HashSet;
37219820Sjeffimport java.util.List;
38219820Sjeffimport java.util.Map;
39219820Sjeffimport java.util.Set;
40219820Sjeffimport java.util.stream.Collectors;
41219820Sjeff
42219820Sjeffimport jdk.tools.jlink.internal.ImagePluginConfiguration;
43219820Sjeffimport jdk.tools.jlink.internal.PluginRepository;
44219820Sjeffimport jdk.tools.jlink.internal.ImagePluginStack;
45219820Sjeffimport jdk.tools.jlink.internal.PoolImpl;
46219820Sjeffimport jdk.tools.jlink.internal.ResourcePrevisitor;
47219820Sjeffimport jdk.tools.jlink.internal.StringTable;
48219820Sjeffimport jdk.tools.jlink.Jlink;
49219820Sjeffimport jdk.tools.jlink.plugin.Plugin;
50219820Sjeffimport jdk.tools.jlink.plugin.Pool;
51219820Sjeffimport jdk.tools.jlink.plugin.Pool.ModuleData;
52219820Sjeffimport jdk.tools.jlink.plugin.TransformerPlugin;
53219820Sjeff
54219820Sjeffpublic class PrevisitorTest {
55219820Sjeff
56219820Sjeff    public static void main(String[] args) throws Exception {
57219820Sjeff        new PrevisitorTest().test();
58219820Sjeff    }
59219820Sjeff
60219820Sjeff    private static Plugin createPlugin(String name) {
61219820Sjeff        return Jlink.newPlugin(name, Collections.emptyMap(), null);
62219820Sjeff    }
63219820Sjeff
64219820Sjeff    public void test() throws Exception {
65219820Sjeff        CustomPlugin plugin = new CustomPlugin();
66219820Sjeff        PluginRepository.registerPlugin(plugin);
67219820Sjeff        List<Plugin> plugins = new ArrayList<>();
68219820Sjeff        plugins.add(createPlugin(CustomPlugin.NAME));
69219820Sjeff        ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new Jlink.PluginsConfiguration(plugins,
70219820Sjeff                null, null));
71219820Sjeff        PoolImpl inResources = new PoolImpl(ByteOrder.nativeOrder(), new CustomStringTable());
72219820Sjeff        inResources.add(Pool.newResource("/aaa/bbb/res1.class", new byte[90]));
73219820Sjeff        inResources.add(Pool.newResource("/aaa/bbb/res2.class", new byte[90]));
74219820Sjeff        inResources.add(Pool.newResource("/aaa/bbb/res3.class", new byte[90]));
75219820Sjeff        inResources.add(Pool.newResource("/aaa/ddd/res1.class", new byte[90]));
76219820Sjeff        inResources.add(Pool.newResource("/aaa/res1.class", new byte[90]));
77219820Sjeff        Pool outResources = stack.visitResources(inResources);
78219820Sjeff        Collection<String> input = inResources.getContent().stream()
79219820Sjeff                .map(Object::toString)
80219820Sjeff                .collect(Collectors.toList());
81219820Sjeff        Collection<String> output = outResources.getContent().stream()
82219820Sjeff                .map(Object::toString)
83219820Sjeff                .collect(Collectors.toList());
84219820Sjeff        if (!input.equals(output)) {
85219820Sjeff            throw new AssertionError("Input and output resources differ: input: "
86219820Sjeff                    + input + ", output: " + output);
87        }
88    }
89
90    private static class CustomStringTable implements StringTable {
91
92        private final List<String> strings = new ArrayList<>();
93
94        @Override
95        public int addString(String str) {
96            strings.add(str);
97            return strings.size() - 1;
98        }
99
100        @Override
101        public String getString(int id) {
102            return strings.get(id);
103        }
104
105        public int size() {
106            return strings.size();
107        }
108    }
109
110    private static class CustomPlugin implements TransformerPlugin, ResourcePrevisitor {
111
112        private static String NAME = "plugin";
113
114        private boolean isPrevisitCalled = false;
115
116        @Override
117        public void visit(Pool inResources, Pool outResources) {
118            if (!isPrevisitCalled) {
119                throw new AssertionError("Previsit was not called");
120            }
121            CustomStringTable table = (CustomStringTable)
122                    ((PoolImpl) inResources).getStringTable();
123            if (table.size() == 0) {
124                throw new AssertionError("Table is empty");
125            }
126            Map<String, Integer> count = new HashMap<>();
127            for (int i = 0; i < table.size(); ++i) {
128                String s = table.getString(i);
129                if (inResources.get(s) != null) {
130                    throw new AssertionError();
131                }
132                count.compute(s, (k, c) -> 1 + (c == null ? 0 : c));
133            }
134            count.forEach((k, v) -> {
135                if (v != 1) {
136                    throw new AssertionError("Expected one entry in the table, got: " + v + " for " + k);
137                }
138            });
139            for (ModuleData r : inResources.getContent()) {
140                outResources.add(r);
141            }
142        }
143
144        @Override
145        public String getName() {
146            return NAME;
147        }
148
149        @Override
150        public void previsit(Pool resources, StringTable strings) {
151            isPrevisitCalled = true;
152            for (ModuleData r : resources.getContent()) {
153                String s = r.getPath();
154                int lastIndexOf = s.lastIndexOf('/');
155                if (lastIndexOf >= 0) {
156                    strings.addString(s.substring(0, lastIndexOf));
157                }
158            }
159        }
160
161        @Override
162        public Set<PluginType> getType() {
163            Set<PluginType> set = new HashSet<>();
164            set.add(CATEGORY.TRANSFORMER);
165            return Collections.unmodifiableSet(set);
166        }
167    }
168}
169