Skip to main content
summaryrefslogblamecommitdiffstats
blob: 518c7b4b1c706ebf5184e300aefd94213e98bc1f (plain) (tree)
1
2
3
4
5
6
7
                                                                                
                                                       



                                                                        
  















                                                                                 

                                        



                                         
                                                              

                                 



















































                                                                                                

                                               






























                                                                                             

                                                               
























                                                                              

                                                       
                                                       

                                                       

















                                                                                                      

                                                       
                                                 

                                                       


























                                                                                                         






                                                                                                                                                                              
                                 









                                                                                                      
                                 
 


                                                                                                                                   
 













                                                                                                         




















                                                                                     
/*******************************************************************************
 * Copyright (c) 2001, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.core.internal.encoding;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Properties;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.sse.core.internal.encoding.util.Logger;
import org.osgi.framework.Bundle;

/**
 * CommonCharsets is a utility class to provide a central place to map some
 * IANA charset name to a Java charset name. In 1.4 JRE's this mostly is a
 * thin wrapper of existing Charset functionality. It does, however, allow
 * some "overriding" of the built in JRE mappings in the event they are
 * necessary. See CodedIO.checkMappingOverrides.
 * <p>
 * This class also provides some convenient human readable description for the
 * charset names which can be used in user interfaces. The description is NL
 * aware based on locale. The data is populated via the charset.properties
 * file only once, based on static initialization of the hashtables.
 * <p>
 * The IANA tags are based on reference information found at the
 * http://www.iana.org site. Specifically see
 * http://www.iana.org/assignments/character-sets
 */
public final class CommonCharsetNames {

	private static Properties defaultIANAmappings = null;

	private static ArrayList encodings = null;

	private static Hashtable supportedEncodingDisplayNames = null;

	/**
	 * Returns list of commonly available encoding names. Suitable for
	 * populating a UI dialog or drop down. This list would be a subset of all
	 * possible charsets the VM supports (which can get into the hundreds).
	 * For the VM supported charsets, use
	 * <code>Charset.availableCharsets()</code>
	 * 
	 * @return String[]
	 */
	public static String[] getCommonCharsetNames() {
		String[] enc = new String[getEncodings().size()];
		getEncodings().toArray(enc);
		return enc;
	}

	/**
	 * @return Returns the defaultIANAmappings.
	 */
	private static Properties getDefaultIANAMappings() {
		if (defaultIANAmappings == null) {
			defaultIANAmappings = new Properties();
			Bundle keyBundle = Platform.getBundle(ICodedResourcePlugin.ID);
			IPath keyPath = new Path("config/defaultIANA.properties"); //$NON-NLS-1$
			URL location = Platform.find(keyBundle, keyPath);
			InputStream propertiesInputStream = null;
			try {
				propertiesInputStream = location.openStream();
				defaultIANAmappings.load(propertiesInputStream);
			}
			catch (IOException e) {
				// if can't read, just assume there's no
				// default IANA mappings
				// and repeated attempts will not occur,
				// since they
				// will be represented by an empty
				// Properties object
			}
		}
		return defaultIANAmappings;
	}

	/**
	 * Returns display (translated) string for encoding name. If there is no
	 * "custom" translated version available, it defers to ther VM's Charset
	 * support. It will return null if no display name is available.
	 * 
	 * @param String
	 *            charset name
	 * @return Human friendly display name
	 */
	public static String getDisplayString(String charsetName) {
		if (charsetName == null)
			return null;
		String result = (String) getSupportedEncodingDisplayNames().get(charsetName);
		if (result == null) {
			// if we don't have a special one, just return
			// what's provided by Charset

			try {
				Charset charset = Charset.forName(charsetName);
				result = charset.displayName();
			}
			catch (UnsupportedCharsetException e) {
				// if not supported, the display name is
				// the least of clients concerns :)
			}
		}
		return result;
	}

	/**
	 * @return Returns the javaEncodings.
	 */
	private static ArrayList getEncodings() {
		if (encodings == null) {
			initHashTables();
		}
		return encodings;
	}

	public static String getIanaPreferredCharsetName(String charsetName) {
		String preferredName = charsetName;

		try {
			Charset charset = Charset.forName(charsetName);
			if (charset.name() != null) {
				preferredName = charset.name();
			}
		}
		catch (IllegalCharsetNameException e) {
			// just return input if illegal
		}
		catch (UnsupportedCharsetException e) {
			// just return input if illegal
		}
		return preferredName;
	}

	/**
	 * Returns a default IANA name that is listed in CommonCharsetNames. Here
	 * is how it checks: 1. check to see if charsetName is in the
	 * CommonCharsetNames list and if so, just return it. 2. check to see if
	 * charsetName is listed in defaultIANAmappings which contains a mapping
	 * of more common encodings and the default IANA name they should map to.
	 * 3. return defaultIanaName if all else fails
	 */
	public static String getPreferredDefaultIanaName(String charsetName, String defaultIanaName) {
		String preferredName = defaultIanaName;
		String guessedName = charsetName;
		try {
			guessedName = CodedIO.getAppropriateJavaCharset(charsetName);
		}
		catch (IllegalCharsetNameException e) {
			// just ignore if illegal
		}
		catch (UnsupportedCharsetException e) {
			// just ignore if illegal
		}
		if (getEncodings().contains(guessedName))
			preferredName = guessedName;
		else {
			preferredName = getDefaultIANAMappings().getProperty(guessedName, preferredName);
		}

		return preferredName;
	}

	/**
	 * @return
	 */
	private static Hashtable getSupportedEncodingDisplayNames() {
		if (supportedEncodingDisplayNames == null) {
			initHashTables();
		}
		return supportedEncodingDisplayNames;
	}

	private static void initHashTables() {
		if (supportedEncodingDisplayNames == null) {
			// Initialize hash table for encoding table
			supportedEncodingDisplayNames = new Hashtable();
			encodings = new ArrayList();

			ResourceBundle bundle = null;
			InputStream bundleStream = null;
			try {
				URL bundleURL = Platform.find(Platform.getBundle(ICodedResourcePlugin.ID), Path.fromOSString("$nl$/config/charset.properties")); //$NON-NLS-1$
				if (bundleURL != null) {
					bundleStream = bundleURL.openStream();
					bundle = new PropertyResourceBundle(bundleStream);
				}

				String totalNumString = bundle.getString("totalnumber");//$NON-NLS-1$
				int totalNum = 0;
				if (totalNumString.length() != 0) {
					try {
						totalNum = Integer.valueOf(totalNumString).intValue();
					}
					catch (NumberFormatException e) {
						totalNum = 0;
					}
				}

				for (int i = 0; i < totalNum; i++) {
					String iana = bundle.getString("codeset." + i + ".iana");//$NON-NLS-2$//$NON-NLS-1$
					String displayName = bundle.getString("codeset." + i + ".label");//$NON-NLS-2$//$NON-NLS-1$

					encodings.add(iana);
					supportedEncodingDisplayNames.put(iana, displayName);
				}
			}
			catch (IOException e) {
				Logger.logException("invalid install or configuration", e); //$NON-NLS-1$
			}
			finally {
				try {
					if (bundleStream != null)
						bundleStream.close();
				}
				catch (IOException x) {
				}
			}
		}
	}

	public static void main(String[] args) {
		// unit test only
		String test = "Cp1252"; //$NON-NLS-1$
		String result = CommonCharsetNames.getIanaPreferredCharsetName(test);
		System.out.println(test + " --> " + result); //$NON-NLS-1$

		test = "MS932"; //$NON-NLS-1$
		result = CommonCharsetNames.getIanaPreferredCharsetName(test);
		System.out.println(test + " --> " + result); //$NON-NLS-1$

	}

	public CommonCharsetNames() {
		super();
		initHashTables();
	}
}

Back to the top