This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 138973
Collapse All | Expand All

(-)a/openide.loaders/test/unit/src/org/openide/loaders/Bug138973Test.java (+352 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.openide.loaders;
41
42
import java.io.BufferedReader;
43
import java.io.BufferedWriter;
44
import java.io.ByteArrayInputStream;
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.io.InputStreamReader;
48
import java.io.OutputStream;
49
import java.io.OutputStreamWriter;
50
import java.io.Reader;
51
import java.io.Writer;
52
import java.nio.ByteBuffer;
53
import java.nio.CharBuffer;
54
import java.nio.charset.Charset;
55
import java.nio.charset.CharsetDecoder;
56
import java.nio.charset.CharsetEncoder;
57
import java.nio.charset.CoderResult;
58
import java.util.Map;
59
import org.netbeans.api.queries.FileEncodingQuery;
60
import org.netbeans.junit.MockServices;
61
import org.netbeans.junit.NbTestCase;
62
import org.netbeans.modules.openide.loaders.DataObjectEncodingQueryImplementation;
63
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
64
import org.openide.filesystems.FileObject;
65
import org.openide.filesystems.FileUtil;
66
import org.openide.util.Lookup;
67
import org.openide.util.lookup.Lookups;
68
69
/**
70
 *
71
 * @author  Marian Petras
72
 */
73
public class Bug138973Test extends NbTestCase {
74
75
    private static final String TESTING_TEXT = "This is a testing text.";
76
    private static final TestCharset TEST_CHARSET = new TestCharset();
77
    private static final String EXT = ".txt";
78
    private static final String TEMPLATE_NAME = "Bug138973TestTemplate";
79
    private static final String TEMPLATE_NAME_EXT = TEMPLATE_NAME + EXT;
80
    private static final String TESTFILE_NAME = "testfile";
81
    private static final String TESTFILE_NAME_EXT = TESTFILE_NAME + EXT;
82
83
    public Bug138973Test() {
84
        super("Bug138973Test");
85
    }
86
87
    public void testBug() throws Exception {
88
        AddLoaderManuallyHid.addRemoveLoader(new SimpleLoader(), true);
89
        MockServices.setServices(SimpleTemplateHandler.class,
90
                                 DataObjectEncodingQueryImplementation.class);
91
92
        FileObject root = FileUtil.createMemoryFileSystem().getRoot();
93
        FileObject templatesFolder = root.createFolder("templates");
94
        assert templatesFolder != null;
95
        FileObject templateFile = FileUtil.createData(templatesFolder,
96
                                                      TEMPLATE_NAME_EXT);
97
        byte[] templateBytes = TESTING_TEXT.getBytes("ISO-8859-1");
98
        InputStream source = new ByteArrayInputStream(templateBytes);
99
        OutputStream target = templateFile.getOutputStream();
100
        FileUtil.copy(source, target);
101
        target.close();
102
        source.close();
103
        assert templateFile.getSize() != 0L;
104
        templateFile.setAttribute("template", Boolean.TRUE);
105
106
        DataObject templateDataObj = DataObject.find(templateFile);
107
        DataObject newDataObj= templateDataObj.createFromTemplate(
108
                                                    DataFolder.findFolder(root),
109
                                                    TESTFILE_NAME);
110
        FileObject newFile = newDataObj.getPrimaryFile();
111
112
        byte[] expectedBytes = new byte[TESTING_TEXT.length() * 4];
113
        TEST_CHARSET.encode(TESTING_TEXT).get(expectedBytes);
114
115
        byte[] actualBytes = new byte[(int) (newFile.getSize())];
116
        InputStream is = null;
117
        try {
118
            is = newFile.getInputStream();
119
            newFile.getInputStream().read(actualBytes);
120
        } finally {
121
            if (is != null) {
122
                is.close();
123
            }
124
        }
125
        assertEquals(expectedBytes, actualBytes);
126
    }
127
128
    private void assertEquals(byte[] expected, byte[] actual) throws Exception {
129
        if ((expected == null) && (actual == null)) {
130
            return;
131
        }
132
        if ((expected == null) || (actual == null)) {
133
            if (actual == null) {
134
                fail("actual is null");
135
            } else{
136
                fail("expected is null");
137
            }
138
        }
139
        if (expected.length != actual.length) {
140
            fail("array lengths differ - expected: "
141
                 + expected.length + ", actual: " + actual.length);
142
        }
143
        for (int i = 0; i < actual.length; i++) {
144
            if (actual[i] != expected[i]) {
145
                String expectedStr = new String(expected, "ISO-8859-1");
146
                String actualStr = new String(actual, "ISO-8859-1");
147
                fail("expected: \"" + expectedStr
148
                     + "\", actual: \"" + actualStr + '"');
149
            }
150
        }
151
    }
152
153
    public static final class SimpleTemplateHandler extends CreateFromTemplateHandler {
154
        @Override
155
        protected boolean accept(FileObject orig) {
156
            return true;
157
        }
158
        @Override
159
        protected FileObject createFromTemplate(FileObject template,
160
                                                FileObject targetFolder,
161
                                                String name,
162
                                                Map<String, Object> parameters) throws IOException {
163
            String nameUniq = FileUtil.findFreeFileName(targetFolder, name, template.getExt());
164
            FileObject newFile = FileUtil.createData(targetFolder, nameUniq + '.' + template.getExt());
165
166
            Charset templateEnc = FileEncodingQuery.getEncoding(template);
167
            Charset newFileEnc = FileEncodingQuery.getEncoding(newFile);
168
169
            InputStream is = template.getInputStream();
170
            Reader reader = new BufferedReader(new InputStreamReader(is, templateEnc));
171
            OutputStream os = newFile.getOutputStream();
172
            Writer writer = new BufferedWriter(new OutputStreamWriter(os, newFileEnc));
173
            int cInt;
174
            while ((cInt = reader.read()) != -1) {
175
                writer.write(cInt);
176
            }
177
            writer.close();
178
            reader.close();
179
180
            return newFile;
181
        }
182
    }
183
184
    public static final class SimpleLoader extends MultiFileLoader {
185
        public SimpleLoader() {
186
            super(SimpleObject.class.getName());
187
        }
188
        protected String displayName() {
189
            return "SimpleLoader";
190
        }
191
        protected FileObject findPrimaryFile(FileObject fo) {
192
            if (fo.getNameExt().equals(TEMPLATE_NAME_EXT)) {
193
                return fo;
194
            }
195
            if (fo.getNameExt().equals(TESTFILE_NAME_EXT)) {
196
                return fo;
197
            }
198
            return null;
199
        }
200
        protected MultiDataObject createMultiObject(FileObject primaryFile)
201
                                            throws DataObjectExistsException,
202
                                                   IOException {
203
            return new SimpleObject(this, primaryFile, isTestingFile(primaryFile));
204
        }
205
        protected MultiDataObject.Entry createPrimaryEntry(MultiDataObject obj,
206
                                                           FileObject primaryFile) {
207
            return new FE(obj, primaryFile);
208
        }
209
        protected MultiDataObject.Entry createSecondaryEntry(MultiDataObject obj,
210
                                                             FileObject secondaryFile) {
211
            return new FE(obj, secondaryFile);
212
        }
213
        private static boolean isTestingFile(FileObject fileObj) {
214
            return fileObj.getNameExt().equals(TESTFILE_NAME_EXT);
215
        }
216
    }
217
218
    private static final class FE extends FileEntry {
219
        public FE(MultiDataObject mo, FileObject fo) {
220
            super(mo, fo);
221
        }
222
        @Override
223
        public FileObject createFromTemplate(FileObject f, String name) throws IOException {
224
            fail("FileEntry.createFromTemplate() should not be called");
225
            return null;
226
        }
227
    }
228
229
    public static final class SimpleObject extends MultiDataObject {
230
        private final Lookup lookup;
231
        public SimpleObject(SimpleLoader l,
232
                            FileObject fo,
233
                            boolean useSpecialEncoding)
234
                                              throws DataObjectExistsException {
235
            super(fo, l);
236
            lookup = useSpecialEncoding
237
                     ? Lookups.fixed(this, new TestEncoding())
238
                     : Lookups.singleton(this);
239
        }
240
        @Override
241
        public String getName() {
242
            return getPrimaryFile().getNameExt();
243
        }
244
        @Override
245
        public Lookup getLookup() {
246
            return lookup;
247
        }
248
    }
249
250
    static final class TestEncoding extends FileEncodingQueryImplementation {
251
        @Override
252
        public Charset getEncoding(FileObject file) {
253
            return TEST_CHARSET;
254
        }
255
    }
256
257
    static final class TestCharset extends Charset {
258
        TestCharset() {
259
            super("test_charset", null);
260
        }
261
        public boolean contains(Charset charset) {
262
            return true;
263
        }
264
        public CharsetDecoder newDecoder() {
265
            return new TestCharsetDecoder(this);
266
        }
267
        public CharsetEncoder newEncoder() {
268
            return new TestCharsetEncoder(this);
269
        }
270
    }
271
272
    static final class TestCharsetDecoder extends CharsetDecoder {
273
        private static final String hexadecimalChars
274
                                    = "0123456789abcdef";               //NOI18N
275
        TestCharsetDecoder(Charset charset) {
276
            super(charset, 1.0f, 1.0f);
277
        }
278
        @Override
279
        protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
280
            for (;;) {
281
                int value = 0;
282
283
                byte b;
284
                char bChar;
285
                int index;
286
287
                if (!in.hasRemaining()) { return CoderResult.UNDERFLOW; }
288
                b = in.get();
289
                bChar = (char) (b >= 0 ? b : b + 256);
290
                index = hexadecimalChars.indexOf(bChar);
291
                if (index == -1) { return CoderResult.malformedForLength(1); }
292
                value = index;
293
294
                if (!in.hasRemaining()) { return CoderResult.UNDERFLOW; }
295
                b = in.get();
296
                bChar = (char) (b >= 0 ? b : b + 256);
297
                index = hexadecimalChars.indexOf(bChar);
298
                if (index == -1) { return CoderResult.malformedForLength(2); }
299
                value = (value << 4) | index;
300
301
                if (!in.hasRemaining()) { return CoderResult.UNDERFLOW; }
302
                b = in.get();
303
                bChar = (char) (b >= 0 ? b : b + 256);
304
                index = hexadecimalChars.indexOf(bChar);
305
                if (index == -1) { return CoderResult.malformedForLength(3); }
306
                value = (value << 4) | index;
307
308
                if (!in.hasRemaining()) { return CoderResult.UNDERFLOW; }
309
                b = in.get();
310
                bChar = (char) (b >= 0 ? b : b + 256);
311
                index = hexadecimalChars.indexOf(bChar);
312
                if (index == -1) { return CoderResult.malformedForLength(4); }
313
                value = (value << 4) | index;
314
315
                if (!out.hasRemaining()) { return CoderResult.OVERFLOW; }
316
                out.put((char) value);
317
            }
318
        }
319
    }
320
321
    /**
322
     * Encodes each character as a series of four hexadecimal digits expressing
323
     * the character's Unicode value.
324
     */
325
    static final class TestCharsetEncoder extends CharsetEncoder {
326
        private static final byte[] hexadecimalChars
327
            = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
328
        TestCharsetEncoder(Charset charset) {
329
            super(charset, 4.0f, 4.0f, new byte[] {0x30, 0x30, 0x33, 0x66});
330
        }
331
        @Override
332
        protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
333
            for (;;) {
334
                if (!in.hasRemaining()) {
335
                    return CoderResult.UNDERFLOW;
336
                }
337
                char c = in.get();
338
                int cInt = (int) c;
339
                if (!out.hasRemaining()) { return CoderResult.OVERFLOW; }
340
                out.put(hexadecimalChars[(cInt >> 12) & 0x000f]);
341
                if (!out.hasRemaining()) { return CoderResult.OVERFLOW; }
342
                out.put(hexadecimalChars[(cInt >>  8) & 0x000f]);
343
                if (!out.hasRemaining()) { return CoderResult.OVERFLOW; }
344
                out.put(hexadecimalChars[(cInt >>  4) & 0x000f]);
345
                if (!out.hasRemaining()) { return CoderResult.OVERFLOW; }
346
                out.put(hexadecimalChars[ cInt        & 0x000f]);
347
            }
348
        }
349
350
    }
351
352
}

Return to bug 138973