/*******************************************************************************
* Copyright (c) 2007-2009 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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
*
* Contributor:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.jsf.vpe.jsf.test.jbide;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IRegion;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import org.jboss.tools.common.model.util.EclipseResourceUtil;
import org.jboss.tools.jsf.vpe.jsf.template.ComponentUtil;
import org.jboss.tools.jsf.vpe.jsf.test.JsfAllTests;
import org.jboss.tools.jst.web.ui.internal.editor.jspeditor.JSPMultiPageEditor;
import org.jboss.tools.test.util.JobUtils;
import org.jboss.tools.vpe.VpePlugin;
import org.jboss.tools.vpe.base.test.TestUtil;
import org.jboss.tools.vpe.base.test.VpeTest;
import org.jboss.tools.vpe.editor.VpeController;
import org.jboss.tools.vpe.editor.util.HTML;
import org.junit.Ignore;
import org.junit.Test;
import org.mozilla.interfaces.nsIDOMDocument;
import org.mozilla.interfaces.nsIDOMElement;
import org.w3c.dom.Element;
import static org.junit.Assert.*;
/**
* Checks f:view's locale workflow.
*
* @author dmaliarevich
*/
public class TestFViewLocaleAttribute_JBIDE5218 extends VpeTest {
private static final String DEFAULT_LOCALE_PAGE = "defaultLocale.jsp"; //$NON-NLS-1$
private static final String LOCALE_ATTRIBUTE_WITH_DEFAULT_LOCALE_PAGE = "localeAndDefault.jsp"; //$NON-NLS-1$
private static final String LOCALE_ATTRIBUTE_PAGE = "JBIDE/5218/localeAttribute.xhtml"; //$NON-NLS-1$
private static final String SEVERAL_FVIEWS_PAGE = "JBIDE/5218/severalFViews.xhtml"; //$NON-NLS-1$
private static final String CHANGE_LOCALE_AND_REFRESH_PAGE = "JBIDE/5218/changeLocaleAndRefresh.xhtml"; //$NON-NLS-1$
private static final String NO_DEFLOC_ATTRIBUTE_PAGE = "Lattr.jsp"; //$NON-NLS-1$
private static final String NO_DEFLOC_SEVERAL_FVIEWS_PAGE = "LSeveral.jsp"; //$NON-NLS-1$
private static final String NO_DEFLOC_CHANGE_REFRESH_PAGE = "LChangeRefresh.jsp"; //$NON-NLS-1$
private static final String NO_DEFLOC_ONE_LOAD_BUNDLE_PAGE = "LOneLoadBundle.jsp"; //$NON-NLS-1$
private static final String HELLO_DE = "Guten Tag!"; //$NON-NLS-1$
private static final String HELLO2_DE = "German Hello"; //$NON-NLS-1$
private static final String HELLO_EN = "Hello (Default)"; //$NON-NLS-1$
private static final String HELLO_EN_US = "US Hello"; //$NON-NLS-1$
private static final String HELLO_EN_GB = "Great Britain Hello"; //$NON-NLS-1$
private static final String LOCALE_TEXT_ID = "localeText"; //$NON-NLS-1$
private static final String LOCALE_TEXT0_ID = "localeText0"; //$NON-NLS-1$
private static final String LOCALE_TEXT1_ID = "localeText1"; //$NON-NLS-1$
private static final String LOCALE_TEXT2_ID = "localeText2"; //$NON-NLS-1$
private static final String LOCALE_TEXT3_ID = "localeText3"; //$NON-NLS-1$
private static final String FVIEW_ID = "fviewid"; //$NON-NLS-1$
private static final String DEFAUT_BUNDLE_NAME = "demo.Messages"; //$NON-NLS-1$
private static final String DEFAUT_MESSAGE_KEY = "hello_message"; //$NON-NLS-1$
private String[] javaSources;
public TestFViewLocaleAttribute_JBIDE5218() {
}
/**
* Tests that the dafault locale is applied by default,
* f:view has no locale attribute in this case.
*
* @throws Throwable
*/
@Test
public void testDefaultLocale() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_I18N_PROJECT_NAME, DEFAULT_LOCALE_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'de' locale", HELLO_DE.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
/**
* The default locale is defined,
* f:view has a locale attribute defined also,
* The default locale in this case should take an advantage.
*
* @throws Throwable
*/
@Test
public void testLocaleAttributeWithDefaultLocale() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_I18N_PROJECT_NAME,
LOCALE_ATTRIBUTE_WITH_DEFAULT_LOCALE_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'de' locale", HELLO_DE.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
/**
* f:view has a locale attribute defined,
* which should be applied.
* Default locale is empty in this case.
*
* @throws Throwable
*/
@Test
public void testLocaleAttribute() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_JSF_20_PROJECT_NAME, LOCALE_ATTRIBUTE_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be should be in 'de' locale", HELLO2_DE.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
/**
* If there are several f:views on the page.
* Only the last f:view one should be applied on server,
* but each f:view should have its own locale.
*
* @throws Throwable
*/
@Test
public void testSeveralFViewsWithLocales() throws Throwable {
IFile file =
(IFile) TestUtil.getComponentPath(SEVERAL_FVIEWS_PAGE, JsfAllTests.IMPORT_JSF_20_PROJECT_NAME);
assertNotNull("Could not open specified file." //$NON-NLS-1$
+ " componentPage = " + SEVERAL_FVIEWS_PAGE //$NON-NLS-1$
+ ";projectName = " + JsfAllTests.IMPORT_JSF_20_PROJECT_NAME, file); //$NON-NLS-1$
IEditorInput input = new FileEditorInput(file);
assertNotNull("Editor input is null", input); //$NON-NLS-1$
/*
* open and get the editor
*/
JSPMultiPageEditor part = openEditor(input);
VpeController controller = TestUtil.getVpeController(part);
javaSources = EclipseResourceUtil.getJavaProjectSrcLocations(file.getProject());
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT0_ID);
String localizedText = getLocalizedText(localeText);
checkLocaleStrings(file, "en", localizedText); //$NON-NLS-1$
localeText = doc.getElementById(LOCALE_TEXT1_ID);
localizedText = getLocalizedText(localeText);
checkLocaleStrings(file, "de", localizedText); //$NON-NLS-1$
localeText = doc.getElementById(LOCALE_TEXT2_ID);
localizedText = getLocalizedText(localeText);
/*
* f:view will use default locale if nothing is specified.
*/
checkLocaleStrings(file, "en_US", localizedText); //$NON-NLS-1$
localeText = doc.getElementById(LOCALE_TEXT_ID);
localizedText = getLocalizedText(localeText);
checkLocaleStrings(file, "en_GB", localizedText); //$NON-NLS-1$
closeEditors();
}
/**
* After the locale attribute value has been changed and
* Refresh button is clicked - the correct locale should be applied,
* bundle messages should be updated and showed in the correct locale.
*
* @throws Throwable
*/
@Test
public void testChangeLocaleAndRefresh() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_JSF_20_PROJECT_NAME,
CHANGE_LOCALE_AND_REFRESH_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'de' locale", HELLO2_DE.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
/*
* Change the locale
*/
Element fViewElement = controller.getSourceBuilder().getSourceDocument().getElementById(FVIEW_ID);
assertTrue("Previous locale should be 'de'", "de".equalsIgnoreCase(fViewElement.getAttribute("locale"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
fViewElement.setAttribute("locale", "en_GB"); //$NON-NLS-1$ //$NON-NLS-2$
/*
* Wait until new value is applied and children are refreshed.
*/
TestUtil.delay(500);
TestUtil.waitForIdle();
assertTrue("Current locale should be 'en_GB'", "en_GB".equalsIgnoreCase(fViewElement.getAttribute("locale"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
doc = controller.getXulRunnerEditor().getDOMDocument();
localeText = doc.getElementById(LOCALE_TEXT_ID);
localizedText = getLocalizedText(localeText);
/*
* Check the new localized message.
*/
assertTrue("Text is '"+localizedText+"', but should be in 'en_GB' locale", HELLO_EN_GB.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
@Test
public void testNoDefaultLocaleForLocaleAttribute() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_JSF_LOCALES_PROJECT_NAME,
NO_DEFLOC_ATTRIBUTE_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'de' locale", HELLO2_DE.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
@Test
@Ignore
public void _testNoDefaultLocaleForSeveralFViews() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_JSF_LOCALES_PROJECT_NAME, NO_DEFLOC_SEVERAL_FVIEWS_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT0_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_US' locale", HELLO_EN_US.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT1_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'default' locale", HELLO_EN.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT2_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'de' locale", HELLO2_DE.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT3_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_US' locale", HELLO_EN_US.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_GB' locale", HELLO_EN_GB.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
@Test
public void testNoDefaultLocaleForChangeAndRefresh() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_JSF_LOCALES_PROJECT_NAME,
NO_DEFLOC_CHANGE_REFRESH_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'de' locale", HELLO2_DE.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
/*
* Change the locale
*/
Element fViewElement = controller.getSourceBuilder().getSourceDocument().getElementById(FVIEW_ID);
int offset = controller.getSourceBuilder().getPosition(fViewElement,0,false);
assertTrue("Previous locale should be 'de'", "de".equalsIgnoreCase(fViewElement.getAttribute("locale"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IRegion reg = new FindReplaceDocumentAdapter(
controller.getSourceBuilder().getStructuredTextViewer().getDocument())
.find(offset, "de", true, true, false, false);
controller.getSourceBuilder().getStructuredTextViewer().getDocument().replace(reg.getOffset(), reg.getLength(), "en_GB");
/*
* Wait until new value is applied and children are refreshed.
* Wait while all deferred events are processed
*/
while(Display.getCurrent().readAndDispatch());
/*
* Wait while all jobs including started through deferred events are ended
*/
JobUtils.delay(VpeController.DEFAULT_UPDATE_DELAY_TIME*4);
TestUtil.waitForIdle();
fViewElement = controller.getSourceBuilder().getSourceDocument().getElementById(FVIEW_ID);
assertTrue("Current locale should be 'en_GB'", "en_GB".equalsIgnoreCase(fViewElement.getAttribute("locale"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
doc = controller.getXulRunnerEditor().getDOMDocument();
localeText = doc.getElementById(LOCALE_TEXT_ID);
localizedText = getLocalizedText(localeText);
/*
* Check the new localized message.
*/
assertTrue("Text is '"+localizedText+"', but should be in 'en_GB' locale", HELLO_EN_GB.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
@Test
public void testNoDefaultLocaleForSingleFLoadBundle() throws Throwable {
VpeController controller = openInVpe(
JsfAllTests.IMPORT_JSF_LOCALES_PROJECT_NAME, NO_DEFLOC_ONE_LOAD_BUNDLE_PAGE);
nsIDOMDocument doc = controller.getXulRunnerEditor().getDOMDocument();
nsIDOMElement localeText = doc.getElementById(LOCALE_TEXT0_ID);
String localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_US' locale", HELLO_EN_US.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT1_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_US' locale", HELLO_EN_US.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT2_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_US' locale", HELLO_EN_US.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT3_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_US' locale", HELLO_EN_US.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
localeText = doc.getElementById(LOCALE_TEXT_ID);
localizedText = getLocalizedText(localeText);
assertTrue("Text is '"+localizedText+"', but should be in 'en_US' locale", HELLO_EN_US.equalsIgnoreCase(localizedText)); //$NON-NLS-1$ //$NON-NLS-2$
closeEditors();
}
/**
* Short version of {@link #checkLocaleStrings(IFile, String, String, String, String)}
* <p>
* Uses default values for bundle name and message key.
*/
private void checkLocaleStrings(IFile openedFile, String localeName, String currentText) {
checkLocaleStrings(openedFile, localeName, DEFAUT_BUNDLE_NAME,
DEFAUT_MESSAGE_KEY, currentText);
}
/**
* Loads a message from resource bundle and
* compares it to the specified one.
* <p>
* Fixes difference in JVM 5 and 6 bundles loading.
*
* @param openedFile file opened in the editor
* @param localeName string code of the locale
* @param bundleName the name of the bundle
* @param bundleKey message key
* @param currentText compared string
*/
private void checkLocaleStrings(IFile openedFile, String localeName,
String bundleName, String bundleKey, String currentText) {
/*
* javaSources should be initialized before call.
*/
URL[] urls = new URL[0];
try {
if (javaSources != null) {
File tempFile;
urls = new URL[javaSources.length];
for (int i = 0; i < javaSources.length; ++i) {
try {
tempFile = new File(javaSources[i]).getCanonicalFile();
urls[i] = tempFile.toURL();
} catch (IOException ioe) {
VpePlugin.reportProblem(ioe);
}
}
}
} catch (MissingResourceException ex) {
VpePlugin.getDefault().logError(
"Project source folder is missing!", ex); //$NON-NLS-1$
}
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader
.getSystemClassLoader());
Locale locale = ComponentUtil.createLocale(localeName);
ResourceBundle bundle = ResourceBundle.getBundle(bundleName,
locale, classLoader);
String bundleText = bundle.getString(bundleKey);
assertNotNull(bundleText);
assertTrue(
"Text is '" + currentText + "', but should be in '"//$NON-NLS-1$ //$NON-NLS-2$
+ localeName
+ "' locale, bundle's value is '" + bundleText + "'", bundleText.equalsIgnoreCase(currentText) //$NON-NLS-1$ //$NON-NLS-2$
);
}
/**
* Gets the text value from the container.
* Container should be a simple tag like div or span.
* The text node in the VPE is initially wrapped in a span element,
* thus to get its value two child elements should be skipped.
*
* @param textContainer - the tag with text
* @return localized by VPE string
*/
private String getLocalizedText(nsIDOMElement textContainer) {
String text = ""; //$NON-NLS-1$
if ((textContainer != null) && (textContainer.getFirstChild() != null)
&& (textContainer.getFirstChild().getFirstChild() != null)
&& HTML.TAG_SPAN.equalsIgnoreCase(textContainer.getFirstChild()
.getNodeName())) {
text = textContainer.getFirstChild().getFirstChild().getNodeValue()
.trim();
}
return text;
}
}