/*
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javadoc;
import java.util.Locale;
import java.util.HashSet;
import java.text.Collator;
import java.text.BreakIterator;
/**
* This class holds the information about locales.
*
* @since 1.4
* @author Robert Field
*/
class DocLocale {
/**
* The locale name will be set by Main, if option is provided on the
* command line.
*/
final String localeName;
/**
* The locale to be used. If user doesen't provide this,
* then set it to default locale value.
*/
final Locale locale;
/**
* The collator for this application. This is to take care of Locale
* Specific or Natural Language Text sorting.
*/
final Collator collator;
/**
* Enclosing DocEnv
*/
private final DocEnv docenv;
/**
* Sentence instance from the BreakIterator.
*/
private final BreakIterator sentenceBreaker;
/**
* True is we should use <code>BreakIterator</code>
* to compute first sentence.
*/
private boolean useBreakIterator = false;
/**
* The HTML sentence terminators.
*/
static final String[] sentenceTerminators =
{
"<p>", "</p>", "<h1>", "<h2>",
"<h3>", "<h4>", "<h5>", "<h6>",
"</h1>", "</h2>", "</h3>", "</h4>", "</h5>",
"</h6>", "<hr>", "<pre>", "</pre>"
};
/**
* Constructor
*/
DocLocale(DocEnv docenv, String localeName, boolean useBreakIterator) {
this.docenv = docenv;
this.localeName = localeName;
this.useBreakIterator = useBreakIterator;
locale = getLocale();
if (locale == null) {
docenv.exit();
} else {
Locale.setDefault(locale);
}
collator = Collator.getInstance(locale);
sentenceBreaker = BreakIterator.getSentenceInstance(locale);
}
/**
* Get the locale if specified on the command line
* else return null and if locale option is not used
* then return default locale.
*/
private Locale getLocale() {
Locale userlocale = null;
if (localeName.length() > 0) {
int firstuscore = localeName.indexOf('_');
int seconduscore = -1;
String language = null;
String country = null;
String variant = null;
if (firstuscore == 2) {
language = localeName.substring(0, firstuscore);
seconduscore = localeName.indexOf('_', firstuscore + 1);
if (seconduscore > 0) {
if (seconduscore != firstuscore + 3 ||
localeName.length() <= seconduscore + 1) {
docenv.error(null, "main.malformed_locale_name", localeName);
return null;
}
country = localeName.substring(firstuscore + 1,
seconduscore);
variant = localeName.substring(seconduscore + 1);
} else if (localeName.length() == firstuscore + 3) {
country = localeName.substring(firstuscore + 1);
} else {
docenv.error(null, "main.malformed_locale_name", localeName);
return null;
}
} else if (firstuscore == -1 && localeName.length() == 2) {
language = localeName;
} else {
docenv.error(null, "main.malformed_locale_name", localeName);
return null;
}
userlocale = searchLocale(language, country, variant);
if (userlocale == null) {
docenv.error(null, "main.illegal_locale_name", localeName);
return null;
} else {
return userlocale;
}
} else {
return Locale.getDefault();
}
}
/**
* Search the locale for specified language, specified country and
* specified variant.
*/
private Locale searchLocale(String language, String country,
String variant) {
Locale[] locales = Locale.getAvailableLocales();
for (int i = 0; i < locales.length; i++) {
if (locales[i].getLanguage().equals(language) &&
(country == null || locales[i].getCountry().equals(country)) &&
(variant == null || locales[i].getVariant().equals(variant))) {
return locales[i];
}
}
return null;
}
String localeSpecificFirstSentence(DocImpl doc, String s) {
if (s == null || s.length() == 0) {
return "";
}
int index = s.indexOf("-->");
if(s.trim().startsWith("<!--") && index != -1) {
return localeSpecificFirstSentence(doc, s.substring(index + 3, s.length()));
}
if (useBreakIterator || !locale.getLanguage().equals("en")) {
sentenceBreaker.setText(s.replace('\n', ' '));
int start = sentenceBreaker.first();
int end = sentenceBreaker.next();
return s.substring(start, end).trim();
} else {
return englishLanguageFirstSentence(s).trim();
}
}
/**
* Return the first sentence of a string, where a sentence ends
* with a period followed be white space.
*/
private String englishLanguageFirstSentence(String s) {
if (s == null) {
return null;
}
int len = s.length();
boolean period = false;
for (int i = 0 ; i < len ; i++) {
switch (s.charAt(i)) {
case '.':
period = true;
break;
case ' ':
case '\t':
case '\n':
case '\r':
case '\f':
if (period) {
return s.substring(0, i);
}
break;
case '<':
if (i > 0) {
if (htmlSentenceTerminatorFound(s, i)) {
return s.substring(0, i);
}
}
break;
default:
period = false;
}
}
return s;
}
/**
* Find out if there is any HTML tag in the given string. If found
* return true else return false.
*/
private boolean htmlSentenceTerminatorFound(String str, int index) {
for (int i = 0; i < sentenceTerminators.length; i++) {
String terminator = sentenceTerminators[i];
if (str.regionMatches(true, index, terminator,
0, terminator.length())) {
return true;
}
}
return false;
}
}