View Javadoc
1   /*
2    * Copyright  2001,2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *
16   */
17  package org.codehaus.plexus.archiver.jar;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.StringWriter;
22  import java.nio.file.Files;
23  import java.util.jar.Attributes;
24  
25  import org.codehaus.plexus.archiver.TestSupport;
26  import org.junit.jupiter.api.Test;
27  
28  import static org.junit.jupiter.api.Assertions.assertEquals;
29  import static org.junit.jupiter.api.Assertions.assertNotNull;
30  import static org.junit.jupiter.api.Assertions.assertNull;
31  import static org.junit.jupiter.api.Assertions.assertTrue;
32  import static org.junit.jupiter.api.Assertions.fail;
33  
34  /**
35   * @author Emmanuel Venisse
36   */
37  class ManifestTest extends TestSupport {
38  
39      @Test
40      void testManifest1() throws Exception {
41          Manifest manifest = getManifest("src/test/resources/manifests/manifest1.mf");
42          String version = manifest.getManifestVersion();
43          assertEquals("1.0", version, "Manifest was not created with correct version - ");
44      }
45  
46      @Test
47      void testManifest2() throws Exception {
48          try {
49              getManifest("src/test/resources/manifests/manifest2.mf");
50              fail("Manifest isn't well formed. It must be generate an exception.");
51          } catch (IOException ignore) {
52          }
53      }
54  
55      @Test
56      void testManifest3() throws Exception {
57          try {
58              getManifest("src/test/resources/manifests/manifest3.mf");
59              fail("Manifest isn't well formed. It must be generate an exception.");
60          } catch (IOException ignore) {
61          }
62      }
63  
64      @Test
65      void testManifest5() throws Exception {
66          try {
67              getManifest("src/test/resources/manifests/manifest5.mf");
68              fail();
69          } catch (IOException ignore) {
70          }
71      }
72  
73      @Test
74      void testAddConfiguredSection() throws ManifestException {
75          Manifest manifest = new Manifest();
76          Manifest.Section section = new Manifest.Section();
77          section.setName("fud");
78          section.addConfiguredAttribute(new Manifest.Attribute("bar", "baz"));
79          manifest.addConfiguredSection(section);
80          assertEquals("baz", manifest.getAttributes("fud").getValue("bar"));
81      }
82  
83      @Test
84      void testAttributeLongLineWrite() throws Exception {
85          StringWriter writer = new StringWriter();
86          Manifest.Attribute attr = new Manifest.Attribute();
87          String longLineOfChars = "123456789 123456789 123456789 123456789 123456789 123456789 123456789 "
88                  + "123456789 123456789 123456789 ";
89          attr.setName("test");
90          attr.setValue(longLineOfChars);
91          attr.write(writer);
92          writer.flush();
93          assertEquals(
94                  "test: 123456789 123456789 123456789 123456789 123456789 123456789 1234" + Manifest.EOL
95                          + " 56789 123456789 123456789 123456789 " + Manifest.EOL,
96                  writer.toString(),
97                  "should be multiline");
98      }
99  
100     @Test
101     void testAttributeLongLineWriteNonAscii() throws Exception {
102         StringWriter writer = new StringWriter();
103         Manifest.Attribute attr = new Manifest.Attribute();
104         String longLineOfChars = "Ед докэндё форынчйбюж зкрипторэм векж, льабятюр ыкжпэтэндяз мэль ут, квюо ут модо "
105                 + "либриз такематыш. Ыюм йн лаборамюз компльыктётюр, векж ыпикурэи дежпютатионй ед,"
106                 + " ыам ты хабымуч мальюизчыт. Но вим алёэнюм вюльпутаты, ад нощтыр трётанё льаборэж"
107                 + " вэл, кевёбюж атоморюм кончюлату векж экз. Ку щольыат вёртюты ёнэрмйщ ыюм.";
108 
109         attr.setName("test");
110         attr.setValue(longLineOfChars);
111         attr.write(writer);
112         writer.flush();
113         assertEquals(
114                 "test: Ед докэндё форынчйбюж зкрипторэм в"
115                         + Manifest.EOL + " екж, льабятюр ыкжпэтэндяз мэль ут, квю"
116                         + Manifest.EOL + " о ут модо либриз такематыш. Ыюм йн лаб"
117                         + Manifest.EOL + " орамюз компльыктётюр, векж ыпикурэи д"
118                         + Manifest.EOL + " ежпютатионй ед, ыам ты хабымуч мальюи"
119                         + Manifest.EOL + " зчыт. Но вим алёэнюм вюльпутаты, ад но"
120                         + Manifest.EOL + " щтыр трётанё льаборэж вэл, кевёбюж ат"
121                         + Manifest.EOL + " оморюм кончюлату векж экз. Ку щольыат "
122                         + Manifest.EOL + " вёртюты ёнэрмйщ ыюм."
123                         + Manifest.EOL,
124                 writer.toString(),
125                 "should be multiline");
126     }
127 
128     @Test
129     void testDualClassPath() throws ManifestException, IOException {
130         Manifest manifest = getManifest("src/test/resources/manifests/manifestWithDualClassPath.mf");
131         final String attribute = manifest.getMainSection().getAttributeValue("Class-Path");
132         // According to discussions, we drop support for duplicate class-path attribute
133         assertEquals("baz", attribute);
134     }
135 
136     @Test
137     void testAttributeMultiLineValue() throws Exception {
138         checkMultiLineAttribute(
139                 "123456789" + Manifest.EOL + "123456789", "123456789" + Manifest.EOL + " 123456789" + Manifest.EOL);
140     }
141 
142     @Test
143     void testAttributeDifferentLineEndings() throws Exception {
144         checkMultiLineAttribute(
145                 "\tA\rB\n\t C\r\n \tD\n\r",
146                 "\tA" + Manifest.EOL + " B" + Manifest.EOL + " \t C" + Manifest.EOL + "  \tD" + Manifest.EOL);
147     }
148 
149     @Test
150     void testAddAttributes() throws ManifestException, IOException {
151         Manifest manifest = getManifest("src/test/resources/manifests/manifestMerge1.mf");
152         Manifest.ExistingSection fudz = manifest.getSection("Fudz");
153         fudz.addConfiguredAttribute(new Manifest.Attribute("boz", "bzz"));
154         assertEquals("bzz", fudz.getAttribute("boz").getValue());
155         assertEquals("bzz", manifest.getSection("Fudz").getAttributeValue("boz"));
156     }
157 
158     @Test
159     void testRemoveAttributes() throws ManifestException, IOException {
160         Manifest manifest = getManifest("src/test/resources/manifests/manifestMerge1.mf");
161         Manifest.ExistingSection fudz = manifest.getSection("Fudz");
162         fudz.addConfiguredAttribute(new Manifest.Attribute("boz", "bzz"));
163         assertEquals("bzz", fudz.getAttributeValue("boz"));
164         fudz.removeAttribute("boz");
165         assertNull(fudz.getAttributeValue("boz"));
166     }
167 
168     @Test
169     void testAttributeSerialization() throws IOException, ManifestException {
170         Manifest manifest = new Manifest();
171         manifest.getMainAttributes().putValue("mfa1", "fud1");
172         manifest.getMainSection().addAttributeAndCheck(new Manifest.Attribute("mfa2", "fud2"));
173         Attributes attributes = new Attributes();
174         attributes.putValue("attA", "baz");
175         manifest.getEntries().put("sub", attributes);
176         manifest.getSection("sub").addAttributeAndCheck(new Manifest.Attribute("attB", "caB"));
177         StringWriter writer = new StringWriter();
178         manifest.write(writer);
179         String s = writer.toString();
180         assertTrue(s.contains("mfa1: fud1"));
181         assertTrue(s.contains("mfa2: fud2"));
182         assertTrue(s.contains("attA: baz"));
183         assertTrue(s.contains("attB: caB"));
184     }
185 
186     @Test
187     void testDefaultBehaviour() {
188         Manifest manifest = new Manifest();
189         Manifest.ExistingSection mainSection = manifest.getMainSection();
190         assertNotNull(mainSection);
191         String bar = mainSection.getAttributeValue("Bar");
192         assertNull(bar);
193         assertNull(manifest.getSection("Fud"));
194     }
195 
196     @Test
197     void testGetDefaultManifest() throws Exception {
198         java.util.jar.Manifest mf = Manifest.getDefaultManifest();
199         java.util.jar.Attributes mainAttributes = mf.getMainAttributes();
200         assertEquals(2, mainAttributes.size());
201         assertTrue(mainAttributes.containsKey(new java.util.jar.Attributes.Name("Manifest-Version")));
202         assertTrue(mainAttributes.containsKey(new java.util.jar.Attributes.Name("Created-By")));
203 
204         mf = Manifest.getDefaultManifest(true);
205         mainAttributes = mf.getMainAttributes();
206         assertEquals(1, mainAttributes.size());
207         assertTrue(mainAttributes.containsKey(new java.util.jar.Attributes.Name("Manifest-Version")));
208     }
209 
210     void checkMultiLineAttribute(String in, String expected) throws Exception {
211         StringWriter writer = new StringWriter();
212         Manifest.Attribute attr = new Manifest.Attribute();
213         attr.setName("test");
214         attr.setValue(in);
215         attr.write(writer);
216         writer.flush();
217 
218         // Print the string with whitespace replaced with special codes
219         // so in case of failure you can see what went wrong.
220         System.err.println("String: " + dumpString(writer.toString()));
221 
222         assertEquals("test: " + expected, writer.toString(), "should be indented multiline");
223     }
224 
225     private static String dumpString(String in) {
226         String out = "";
227 
228         char[] chars = in.toCharArray();
229 
230         for (char aChar : chars) {
231             switch (aChar) {
232                 case '\t':
233                     out += "\\t";
234                     break;
235                 case '\r':
236                     out += "\\r";
237                     break;
238                 case '\n':
239                     out += "\\n";
240                     break;
241                 case ' ':
242                     out += "\\s";
243                     break;
244                 default:
245                     out += aChar;
246                     break;
247             }
248         }
249 
250         return out;
251     }
252 
253     @Test
254     void testAddAttributesPlexusManifest() throws ManifestException, IOException {
255         Manifest manifest = getManifest("src/test/resources/manifests/manifestMerge1.mf");
256         Manifest.ExistingSection fudz = manifest.getSection("Fudz");
257         fudz.addConfiguredAttribute(new Manifest.Attribute("boz", "bzz"));
258         assertEquals("bzz", manifest.getSection("Fudz").getAttributeValue("boz"));
259     }
260 
261     @Test
262     void testRemoveAttributesPlexusManifest() throws ManifestException, IOException {
263         Manifest manifest = getManifest("src/test/resources/manifests/manifestMerge1.mf");
264         Manifest.ExistingSection fudz = manifest.getSection("Fudz");
265         fudz.addConfiguredAttribute(new Manifest.Attribute("boz", "bzz"));
266         assertEquals("bzz", fudz.getAttributeValue("boz"));
267         fudz.removeAttribute("boz");
268         assertNull(fudz.getAttributeValue("boz"));
269     }
270 
271     @Test
272     void testAttributeSerializationPlexusManifest() throws IOException, ManifestException {
273         Manifest manifest = new Manifest();
274         manifest.getMainSection().addConfiguredAttribute(new Manifest.Attribute("mfa1", "fud1"));
275         manifest.getMainSection().addConfiguredAttribute(new Manifest.Attribute("mfa2", "fud2"));
276         Manifest.Section attributes = new Manifest.Section();
277         attributes.setName("TestSection");
278         attributes.addConfiguredAttribute(new Manifest.Attribute("attA", "baz"));
279         attributes.addConfiguredAttribute(new Manifest.Attribute("attB", "caB"));
280         manifest.addConfiguredSection(attributes);
281         StringWriter writer = new StringWriter();
282         manifest.write(writer);
283         String s = writer.toString();
284         assertTrue(s.contains("mfa1: fud1"));
285         assertTrue(s.contains("mfa2: fud2"));
286         assertTrue(s.contains("attA: baz"));
287         assertTrue(s.contains("attB: caB"));
288     }
289 
290     @Test
291     void testClassPathPlexusManifest() throws ManifestException {
292         Manifest manifest = new Manifest();
293         manifest.addConfiguredAttribute(new Manifest.Attribute(ManifestConstants.ATTRIBUTE_CLASSPATH, "fud"));
294         manifest.addConfiguredAttribute(new Manifest.Attribute(ManifestConstants.ATTRIBUTE_CLASSPATH, "duf"));
295         assertEquals("fud duf", manifest.getMainSection().getAttributeValue(ManifestConstants.ATTRIBUTE_CLASSPATH));
296     }
297 
298     @Test
299     void testAddConfiguredSectionPlexusManifest() throws ManifestException {
300         Manifest manifest = new Manifest();
301         Manifest.Section section = new Manifest.Section();
302         section.setName("fud");
303         section.addConfiguredAttribute(new Manifest.Attribute("bar", "baz"));
304         manifest.addConfiguredSection(section);
305         assertEquals("baz", manifest.getSection("fud").getAttributeValue("bar"));
306     }
307 
308     /**
309      * Reads a Manifest file.
310      *
311      * @param filename the file
312      *
313      * @return a manifest
314      *
315      * @throws java.io.IOException
316      * @throws ManifestException
317      */
318     private Manifest getManifest(String filename) throws IOException, ManifestException {
319         try (InputStream is = Files.newInputStream(getTestFile(filename).toPath())) {
320             return new Manifest(is);
321         }
322     }
323 }