/*
* -----------------------------------------------------------------------
* File: $HeadURL: http://keith-laptop/svn/krs/LanguageTest/trunk/org.thanlwinsoft.languagetest/src/org/thanlwinsoft/languagetest/language/test/UniversalLanguage.java $
* Revision $LastChangedRevision: 936 $
* Last Modified: $LastChangedDate: 2007-08-03 05:14:14 +0700 (Fri, 03 Aug 2007) $
* Last Change by: $LastChangedBy: keith $
* -----------------------------------------------------------------------
* Copyright (C) 2004 Keith Stribley <devel@thanlwinsoft.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
* -----------------------------------------------------------------------
*/
package org.thanlwinsoft.languagetest.language.test;
import java.util.regex.Pattern;
import org.thanlwinsoft.languagetest.MessageUtil;
import org.thanlwinsoft.languagetest.language.text.Iso15924;
import org.thanlwinsoft.languagetest.language.text.Iso3166;
import org.thanlwinsoft.languagetest.language.text.Iso639;
/**
* A version of locale that allows empty language and country strings
* @author keith
*/
public class UniversalLanguage
{
/** Creates a new instance of UniversalLocale */
private String langCode = "";
private String countryCode = "";
private String variant = "";
private String script = "";
private String encoding = "";
private String description = "";
private String completeCode = "";
private static final Pattern langPattern = Pattern.compile("[a-z]{2,3}");
private static final Pattern countryPattern = Pattern.compile("[A-Z]{2}");
private static final Pattern variantPattern = Pattern.compile("[A-Za-z0-9]*");
private static final Pattern scriptPattern = Pattern.compile("[A-Z][a-z]{3}");
private static final Pattern encodingPattern = Pattern.compile("[A-Za-z0-9-_]*");
public static final int NATIVE_LANG = 0;
public static final int FOREIGN_LANG = 1;
private boolean valid = false;
public UniversalLanguage(String code)
{
this.completeCode = code;
int scriptStart = code.indexOf('[');
int scriptStop = code.indexOf(']');
if (scriptStart > -1 && scriptStop > scriptStart)
{
String fullScript = code.substring(scriptStart + 1, scriptStop);
int dotIndex = fullScript.indexOf('.');
if (dotIndex > -1)
{
this.script = fullScript.substring(0, dotIndex);
this.encoding = fullScript.substring(dotIndex + 1);
}
else this.script = fullScript;
}
else
{
scriptStart = code.length();
}
int firstUnderScore = code.indexOf('_');
if (firstUnderScore > -1)
{
this.langCode = code.substring(0,firstUnderScore);
int secondUnderScore = code.indexOf('_',firstUnderScore + 1);
if (secondUnderScore > -1)
{
countryCode = code.substring(firstUnderScore + 1,
secondUnderScore);
variant = code.substring(secondUnderScore + 1, scriptStart);
}
else
{
countryCode = code.substring(firstUnderScore + 1,
scriptStart);
}
}
else // appears to only have a language code
{
this.langCode = code.substring(0, scriptStart);
}
this.description = generateDescription();
validate();
}
public UniversalLanguage(String language, String country,
String variant, String script, String encoding)
throws IllegalArgumentException
{
createFromParts(language, country, variant, script, encoding);
}
public UniversalLanguage(String [] parts)
throws IllegalArgumentException
{
if (parts.length > 0) langCode = parts[0];
if (parts.length > 1) countryCode = parts[1];
if (parts.length > 2) variant = parts[2];
if (parts.length > 3) script = parts[3];
if (parts.length > 4) encoding = parts[4];
createFromParts(langCode, countryCode, variant, script, encoding);
}
protected void createFromParts(String language, String country,
String variant, String script, String encoding)
{
this.langCode = language;
this.countryCode = country;
this.variant = variant;
this.script = script;
this.encoding = encoding;
validate();
this.description = generateDescription();
StringBuffer b = new StringBuffer();
b.delete(0, b.length());
b.append(langCode);
if (countryCode.length()>0 || variant.length() > 0)
{
b.append('_');
b.append(countryCode);
}
if (variant.length() > 0)
{
b.append('_');
b.append(variant);
}
if (script.length() > 0)
{
b.append('[');
b.append(script);
if (encoding.length() > 0)
{
b.append('.');
b.append(encoding);
}
b.append(']');
}
completeCode = b.toString();
b.delete(0, b.length());
}
private boolean validate() throws IllegalArgumentException
{
valid = langPattern.matcher(langCode).matches();
valid &= Iso639.isValidCode(langCode);
if (!valid)
{
throw new IllegalArgumentException(MessageUtil.getString("InvalidLanguage",
toString()));
}
if (countryCode.length() > 0)
{
valid &= countryPattern.matcher(countryCode).matches();
if (!valid)
{
throw new IllegalArgumentException(MessageUtil.getString("InvalidCountry",
countryCode));
}
}
valid &= variantPattern.matcher(variant).matches();
if (!valid)
{
throw new IllegalArgumentException(MessageUtil.getString("InvalidVariant",
variant));
}
if (script.length() > 0)
{
valid &= scriptPattern.matcher(script).matches();
if (!valid)
{
throw new IllegalArgumentException(MessageUtil.getString("InvalidScript",
script));
}
valid &= encodingPattern.matcher(encoding).matches();
if (!valid)
{
throw new IllegalArgumentException(MessageUtil.getString("InvalidEncoding",
encoding));
}
}
return valid;
}
public String getICUlocaleID()
{
if (countryCode.length()> 0)
{
if (script.length() > 0)
{
return langCode + "_" + script + "_" + countryCode;
}
else
{
return langCode + "_" + countryCode;
}
}
else if (script.length() > 0)
{
return langCode + "_" + script;
}
return langCode;
}
protected String generateDescription()
{
StringBuffer b = new StringBuffer(Iso639.getDescription(langCode));
if (countryCode.length()>0)
{
b.append('(');
b.append(Iso3166.getDescriptionFromCode(countryCode));
if (variant.length() > 0)
{
b.append(',');
b.append(variant);
}
b.append(')');
}
else if (variant.length() > 0)
{
b.append('(');
b.append(variant);
b.append(')');
}
if (script.length()>0)
{
b.append(" [Script: ");
b.append(Iso15924.getDescription(script));
if (encoding.length() > 0)
{
b.append(", ");
b.append(encoding);
}
b.append(']');
}
return b.toString();
}
public String getCountryCode()
{
return countryCode;
}
public String getLanguageCode()
{
return langCode;
}
public String getCode()
{
return completeCode;
}
public String getVariant()
{
return variant;
}
public String getScriptCode()
{
return script;
}
public boolean equals(Object o)
{
if (o instanceof UniversalLanguage)
{
return ((UniversalLanguage)o).getCode().equals(getCode());
}
return false;
}
public int hashCode()
{
return completeCode.hashCode();
}
public String getDescription()
{
return description;
}
/**
* The user may prefer a different description to the default generated one
*/
public void setDescription(String newDesc)
{
description = newDesc;
}
public boolean isValid()
{
return valid;
}
public String toString()
{
return description;
}
public String [] toArray()
{
return new String[] { langCode, countryCode, variant, script, encoding };
}
}