| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package tests.api.java.nio.charset; |
| |
| import dalvik.annotation.KnownFailure; |
| import dalvik.annotation.TestLevel; |
| import dalvik.annotation.TestTargetClass; |
| import dalvik.annotation.TestTargetNew; |
| import dalvik.annotation.TestTargets; |
| import dalvik.annotation.AndroidOnly; |
| |
| import junit.framework.TestCase; |
| |
| import tests.api.java.nio.charset.CharsetTest.MockCharset; |
| import tests.api.java.nio.charset.CharsetTest.MockSecurityManager; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.OutputStreamWriter; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLClassLoader; |
| import java.nio.charset.Charset; |
| import java.nio.charset.UnsupportedCharsetException; |
| import java.nio.charset.spi.CharsetProvider; |
| import java.util.Iterator; |
| import java.util.SortedMap; |
| import java.util.Vector; |
| |
| @TestTargetClass(CharsetProvider.class) |
| /** |
| * Test charset providers managed by Charset. |
| */ |
| public class CharsetProviderTest extends TestCase { |
| |
| // need to be modified, e.g., read from system property |
| static String PROP_CONFIG_FILE1 = "clear.tests.cp1"; |
| |
| static String CONFIG_FILE1 = null; |
| |
| |
| static MockCharset charset1 = new MockCharset("mockCharset00", |
| new String[] { "mockCharset01", "mockCharset02" }); |
| |
| static MockCharset charset2 = new MockCharset("mockCharset10", |
| new String[] { "mockCharset11", "mockCharset12" }); |
| |
| @Override |
| protected void setUp() { |
| String tmpDir = System.getProperty("java.io.tmpdir"); |
| if (tmpDir == null) { |
| fail("java.io.tmpdir not set"); |
| } |
| |
| File tmpdir = new File(tmpDir); |
| if (!tmpdir.isDirectory()) { |
| fail("java.io.tmpdir is not a directory"); |
| } |
| |
| String sep = System.getProperty("file.separator"); |
| |
| if (!tmpDir.endsWith(sep)) { |
| tmpDir += sep; |
| } |
| |
| CONFIG_FILE1 = tmpDir + "META-INF" + sep + "services" + sep |
| + "java.nio.charset.spi.CharsetProvider"; |
| |
| URL url = null; |
| try { |
| url = new URL("file://" + tmpDir); |
| } catch (MalformedURLException e) { |
| fail("unexpected exception: " + e); |
| } |
| |
| ClassLoader parent = Thread.currentThread().getContextClassLoader(); |
| if (parent == null) { |
| parent = ClassLoader.getSystemClassLoader(); |
| } |
| |
| URLClassLoader urlc = new URLClassLoader(new URL[] { url }, parent); |
| |
| Thread.currentThread().setContextClassLoader(urlc); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| Thread.currentThread().setContextClassLoader(null); |
| } |
| |
| /* |
| * Write the string to the config file. |
| */ |
| private void setupFile(String path, String content) throws Exception { |
| String sep = System.getProperty("file.separator"); |
| int sepIndex = path.lastIndexOf(sep); |
| File f = new File(path.substring(0, sepIndex)); |
| f.mkdirs(); |
| |
| FileOutputStream fos = new FileOutputStream(path); |
| OutputStreamWriter writer = new OutputStreamWriter(fos);// , "UTF-8"); |
| try { |
| writer.write(content); |
| } finally { |
| writer.close(); |
| } |
| } |
| |
| /* |
| * Write the string to the config file. |
| */ |
| private void cleanupFile(String path) throws Exception { |
| File f = new File(path); |
| f.delete(); |
| } |
| |
| /* |
| * Test the method isSupported(String) with charset supported by some |
| * providers (multiple). |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| @AndroidOnly("Looks like RI doesn't use current thread's context class "+ |
| "loader to lookup charset providers") |
| public void testIsSupported_And_ForName_NormalProvider() throws Exception { |
| try { |
| assertFalse(Charset.isSupported("mockCharset10")); |
| assertFalse(Charset.isSupported("mockCharset11")); |
| assertFalse(Charset.isSupported("mockCharset12")); |
| try { |
| Charset.forName("mockCharset10"); |
| fail("Should throw UnsupportedCharsetException!"); |
| } catch (UnsupportedCharsetException e) { |
| // expected |
| } |
| try { |
| Charset.forName("mockCharset11"); |
| fail("Should throw UnsupportedCharsetException!"); |
| } catch (UnsupportedCharsetException e) { |
| // expected |
| } |
| try { |
| Charset.forName("mockCharset12"); |
| fail("Should throw UnsupportedCharsetException!"); |
| } catch (UnsupportedCharsetException e) { |
| // expected |
| } |
| |
| StringBuffer sb = new StringBuffer(); |
| sb.append("#comment\r"); |
| sb.append("\n"); |
| sb.append("\r\n"); |
| sb.append(" \ttests.api.java.nio.charset." |
| + "CharsetTest$MockCharsetProvider \t\n\r"); |
| sb.append(" \ttests.api.java.nio.charset." |
| + "CharsetTest$MockCharsetProvider \t"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| sb = new StringBuffer(); |
| sb.append(" #comment\r"); |
| sb.append("\n"); |
| sb.append("\r\n"); |
| sb.append(" \ttests.api.java.nio.charset." |
| + "CharsetProviderTest$MockCharsetProvider \t\n\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| assertTrue(Charset.isSupported("mockCharset10")); |
| // ignore case problem in mock, intended |
| assertTrue(Charset.isSupported("MockCharset11")); |
| assertTrue(Charset.isSupported("MockCharset12")); |
| assertTrue(Charset.isSupported("MOCKCharset10")); |
| // intended case problem in mock |
| assertTrue(Charset.isSupported("MOCKCharset11")); |
| assertTrue(Charset.isSupported("MOCKCharset12")); |
| |
| assertTrue(Charset.forName("mockCharset10") instanceof MockCharset); |
| assertTrue(Charset.forName("mockCharset11") instanceof MockCharset); |
| assertTrue(Charset.forName("mockCharset12") instanceof MockCharset); |
| |
| assertTrue(Charset.forName("mockCharset10") == charset2); |
| // intended case problem in mock |
| Charset.forName("mockCharset11"); |
| assertTrue(Charset.forName("mockCharset12") == charset2); |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method isSupported(String) when the configuration file contains |
| * a non-existing class name. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| public void testIsSupported_NonExistingClass() throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("impossible\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.isSupported("impossible"); |
| fail("Should throw Error!"); |
| } catch (Error e) { |
| // expected |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method isSupported(String) when the configuration file contains |
| * a non-CharsetProvider class name. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| @AndroidOnly("Looks like RI doesn't use current thread's context class "+ |
| "loader to lookup charset providers") |
| public void testIsSupported_NotCharsetProviderClass() throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("java.lang.String\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.isSupported("impossible"); |
| fail("Should throw ClassCastException!"); |
| } catch (ClassCastException e) { |
| // expected |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method isSupported(String) with insufficient privilege to use |
| * charset provider. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| @KnownFailure("Android throws Error in case of insufficient privileges, " + |
| "RI throws SecurityException") |
| public void testIsSupported_InsufficientPrivilege() throws Exception { |
| SecurityManager oldMan = System.getSecurityManager(); |
| System.setSecurityManager(new MockSecurityManager()); |
| try { |
| Charset.isSupported("UTF-8"); |
| |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("tests.api.java.nio.charset." |
| + "CharsetProviderTest$MockCharsetProvider\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| assertFalse(Charset.isSupported("gb180300000")); |
| } catch (SecurityException e) { |
| fail("unexpected SecurityException!:" + e); |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } finally { |
| System.setSecurityManager(oldMan); |
| } |
| } |
| |
| /* |
| * Test the method isSupported(String) with insufficient privilege to use |
| * charset provider. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| @KnownFailure("Android throws Error in case of insufficient privileges, " + |
| "RI throws SecurityException") |
| public void testForName_InsufficientPrivilege() throws Exception { |
| SecurityManager oldMan = System.getSecurityManager(); |
| System.setSecurityManager(new MockSecurityManager()); |
| try { |
| Charset.forName("UTF-8"); |
| |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("tests.api.java.nio.charset." |
| + "CharsetProviderTest$MockCharsetProvider\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.forName("gb180300000"); |
| fail("expected UnsupportedCharsetException!"); |
| } catch (SecurityException e) { |
| fail("unexpected SecurityException!:" + e); |
| } catch (UnsupportedCharsetException e) { |
| // ok |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } finally { |
| System.setSecurityManager(oldMan); |
| } |
| } |
| |
| /* |
| * Test the method forName(String) when the charset provider supports a |
| * built-in charset. |
| */ |
| @TestTargets({ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsets", |
| args = {} |
| ), |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| }) |
| public void testForName_DuplicateWithBuiltInCharset() throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("tests.api.java.nio.charset." + |
| "CharsetProviderTest$MockCharsetProviderACSII\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| assertFalse(Charset.forName("us-ascii") instanceof MockCharset); |
| Charset charset = Charset.availableCharsets().get("us-ascii"); |
| assertFalse(charset instanceof MockCharset); |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method forName(String) when the configuration file contains a |
| * non-existing class name. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| @AndroidOnly("Looks like RI doesn't use current thread's context class "+ |
| "loader to lookup charset providers") |
| public void testForName_NonExistingClass() throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("impossible\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.forName("impossible"); |
| fail("Should throw Error!"); |
| } catch (Error e) { |
| // expected |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method forName(String) when the configuration file contains a |
| * non-CharsetProvider class name. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsetForName", |
| args = {String.class} |
| ) |
| @AndroidOnly("Looks like RI doesn't use current thread's context class "+ |
| "loader to lookup charset providers") |
| public void testForName_NotCharsetProviderClass() throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("java.lang.String\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.forName("impossible"); |
| fail("Should throw ClassCastException!"); |
| } catch (ClassCastException e) { |
| // expected |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method availableCharsets() with charset supported by some |
| * providers (multiple). |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsets", |
| args = {} |
| ) |
| @AndroidOnly("Looks like RI doesn't use current thread's context class "+ |
| "loader to lookup charset providers") |
| public void testAvailableCharsets_NormalProvider() throws Exception { |
| try { |
| assertFalse(Charset.availableCharsets() |
| .containsKey("mockCharset10")); |
| assertFalse(Charset.availableCharsets() |
| .containsKey("mockCharset11")); |
| assertFalse(Charset.availableCharsets() |
| .containsKey("mockCharset12")); |
| |
| StringBuffer sb = new StringBuffer(); |
| sb.append("#comment\r"); |
| sb.append("\n"); |
| sb.append("\r\n"); |
| sb.append("\ttests.api.java.nio.charset." |
| + "CharsetTest$MockCharsetProvider \t\n\r"); |
| sb.append("\ttests.api.java.nio.charset." |
| + "CharsetTest$MockCharsetProvider \t"); |
| sb.append("#comment\r"); |
| sb.append("\n"); |
| sb.append("\r\n"); |
| sb.append(" \ttests.api.java.nio.charset." |
| + "CharsetProviderTest$MockCharsetProvider \t\n\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| SortedMap<String, Charset> availableCharsets = Charset |
| .availableCharsets(); |
| assertTrue(availableCharsets.containsKey("mockCharset00")); |
| assertTrue(availableCharsets.containsKey("MOCKCharset00")); |
| Charset charset = availableCharsets.get("mockCharset00"); |
| assertTrue(charset instanceof MockCharset); |
| |
| charset = availableCharsets.get("MOCKCharset00"); |
| assertTrue(charset instanceof MockCharset); |
| |
| assertFalse(availableCharsets.containsKey("mockCharset01")); |
| assertFalse(availableCharsets.containsKey("mockCharset02")); |
| |
| charset = availableCharsets.get("mockCharset10"); |
| assertTrue(charset == charset2); |
| |
| charset = availableCharsets.get("MOCKCharset10"); |
| assertTrue(charset == charset2); |
| |
| assertFalse(availableCharsets.containsKey("mockCharset11")); |
| assertFalse(availableCharsets.containsKey("mockCharset12")); |
| |
| assertTrue(availableCharsets.containsKey("mockCharset10")); |
| assertTrue(availableCharsets.containsKey("MOCKCharset10")); |
| |
| charset = availableCharsets.get("mockCharset10"); |
| assertTrue(charset == charset2); |
| |
| assertFalse(availableCharsets.containsKey("mockCharset11")); |
| assertFalse(availableCharsets.containsKey("mockCharset12")); |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method availableCharsets(String) when the configuration file |
| * contains a non-existing class name. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsets", |
| args = {} |
| ) |
| public void testAvailableCharsets_NonExistingClass() throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("impossible\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.availableCharsets(); |
| fail("Should throw Error!"); |
| } catch (Error e) { |
| // expected |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method availableCharsets(String) when the configuration file |
| * contains a non-CharsetProvider class name. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsets", |
| args = {} |
| ) |
| @AndroidOnly("Looks like RI doesn't use current thread's context class "+ |
| "loader to lookup charset providers") |
| public void testAvailableCharsets_NotCharsetProviderClass() |
| throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("java.lang.String\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.availableCharsets(); |
| fail("Should throw ClassCastException!"); |
| } catch (ClassCastException e) { |
| // expected |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Test the method availableCharsets(String) when the configuration file |
| * contains an illegal string. |
| */ |
| @TestTargetNew( |
| level = TestLevel.PARTIAL_COMPLETE, |
| notes = "", |
| method = "charsets", |
| args = {} |
| ) |
| public void testAvailableCharsets_IllegalString() throws Exception { |
| try { |
| StringBuffer sb = new StringBuffer(); |
| sb.append("java String\r"); |
| setupFile(CONFIG_FILE1, sb.toString()); |
| |
| Charset.availableCharsets(); |
| fail("Should throw Error!"); |
| } catch (Error e) { |
| // expected |
| } finally { |
| cleanupFile(CONFIG_FILE1); |
| } |
| } |
| |
| /* |
| * Mock charset provider. |
| */ |
| public static class MockCharsetProvider extends CharsetProvider { |
| |
| public Charset charsetForName(String charsetName) { |
| if ("MockCharset10".equalsIgnoreCase(charsetName) |
| || "MockCharset11".equalsIgnoreCase(charsetName) |
| || "MockCharset12".equalsIgnoreCase(charsetName)) { |
| return charset2; |
| } |
| return null; |
| } |
| |
| public Iterator<Charset> charsets() { |
| Vector<Charset> v = new Vector<Charset>(); |
| v.add(charset2); |
| return v.iterator(); |
| } |
| } |
| |
| /* |
| * Another mock charset provider providing build-in charset "ascii". |
| */ |
| public static class MockCharsetProviderACSII extends CharsetProvider { |
| |
| public Charset charsetForName(String charsetName) { |
| if ("US-ASCII".equalsIgnoreCase(charsetName) |
| || "ASCII".equalsIgnoreCase(charsetName)) { |
| return new MockCharset("US-ASCII", new String[] { "ASCII" }); |
| } |
| return null; |
| } |
| |
| public Iterator<Charset> charsets() { |
| Vector<Charset> v = new Vector<Charset>(); |
| v.add(new MockCharset("US-ASCII", new String[] { "ASCII" })); |
| return v.iterator(); |
| } |
| } |
| |
| } |