org.osgi.framework.security=osgi
java.security.policy=file:../../all.policy
+# i18n
+argeo.i18n.defaultLocale=fr
+argeo.i18n.locales=en,fr
+eclipse.registry.MultiLanguage=true
+
log4j.configuration=file:../../log4j.properties
org.eclipse.rap.workbenchAutostart=false
\ No newline at end of file
# cd ssl; sh ./ssl.sh;
# i18n
-argeo.i18n.availableLocales=en,fr,de
+argeo.i18n.locales=en,fr,de
eclipse.registry.MultiLanguage=true
# Logging
public final static Msg login = new Msg("sign in");
public final static Msg register = new Msg("register");
+ public final static Msg changePassword = new Msg("change password");
+ public final static Msg currentPassword = new Msg("current password");
+ public final static Msg newPassword = new Msg("new password");
+ public final static Msg repeatNewPassword = new Msg("repeat new password");
+ public final static Msg passwordChanged = new Msg("password changed");
+
static {
Msg.init(CmsMsg.class);
}
password=mot de passe
logout=déconnexion
login=connexion
-register=créer un compte
\ No newline at end of file
+register=créer un compte
+
+changePassword=changement de mot de passe
+currentPassword=mot de passe actuel
+newPassword=nouveau mot de passe
+repeatNewPassword=répéter le nouveau mot de passe
+passwordChanged=mot de passe changé
/** When used as the first word of a sentence. */
public String lead() {
- String raw = toString();
- return raw.substring(0, 1).toUpperCase(UiContext.getLocale())
- + raw.substring(1);
+ return lead(UiContext.getLocale());
+ }
+
+ public String lead(Locale locale) {
+ return lead(this, locale);
+ }
+
+ private static String lead(Msg msg, Locale locale) {
+ String raw = msg.local(locale).toString();
+ return lead(raw, locale);
+ }
+
+ public static String lead(String raw, Locale locale) {
+ return raw.substring(0, 1).toUpperCase(locale) + raw.substring(1);
}
public Object local() {
return local;
}
+ public Object local(Locale locale) {
+ Object local = local(this, locale);
+ if (local == null)
+ local = getDefault();
+ if (local == null)
+ throw new CmsException("No translation found for " + id);
+ return local;
+ }
+
private static Object local(Msg msg) {
+ Locale locale = UiContext.getLocale();
+ return local(msg, locale);
+ }
+
+ private static Object local(Msg msg, Locale locale) {
String key = msg.getId();
int lastDot = key.lastIndexOf('.');
String className = key.substring(0, lastDot);
String fieldName = key.substring(lastDot + 1);
- Locale locale = UiContext.getLocale();
ResourceBundle rb = ResourceBundle.getBundle(className, locale,
msg.getClassLoader());
return rb.getString(fieldName);
LocaleChoice callback = (LocaleChoice) callbacks[i];
writer.write("Language");
writer.write("\n");
- for (int j = 0; j < callback.getAvailableLocales().size(); j++) {
- Locale locale = callback.getAvailableLocales().get(j);
+ for (int j = 0; j < callback.getLocales().size(); j++) {
+ Locale locale = callback.getLocales().get(j);
writer.print(j + " : " + locale.getDisplayName() + "\n");
}
writer.write("(" + callback.getDefaultIndex() + ") : ");
import static bitronix.tm.TransactionManagerServices.getTransactionManager;
import static bitronix.tm.TransactionManagerServices.getTransactionSynchronizationRegistry;
+import static java.util.Locale.ENGLISH;
import static org.argeo.cms.internal.kernel.KernelUtils.getFrameworkProp;
import static org.argeo.cms.internal.kernel.KernelUtils.getOsgiInstancePath;
import static org.argeo.jcr.ArgeoJcrConstants.ALIAS_NODE;
import static org.argeo.jcr.ArgeoJcrConstants.JCR_REPOSITORY_ALIAS;
+import static org.argeo.util.LocaleChoice.asLocaleList;
import static org.osgi.framework.Constants.FRAMEWORK_UUID;
import java.io.File;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.List;
+import java.util.Locale;
import java.util.Map;
import javax.jcr.Repository;
private DataHttp dataHttp;
private KernelThread kernelThread;
+ private Locale defaultLocale = null;
+ private List<Locale> locales = null;
+
public Kernel() {
nodeSecurity = new NodeSecurity();
}
Thread.currentThread().setContextClassLoader(
Kernel.class.getClassLoader());
// KernelUtils.logFrameworkProperties(log);
+ defaultLocale = new Locale(getFrameworkProp(I18N_DEFAULT_LOCALE,
+ ENGLISH.getLanguage()));
+ locales = asLocaleList(getFrameworkProp(I18N_LOCALES));
try {
// Initialise services
logger = new NodeLogger();
- // transactionManager = new SimpleTransactionManager();
initBitronixTransactionManager();
repository = new NodeRepository(bc);
repositoryFactory = new OsgiJackrabbitRepositoryFactory();
+ (httpsPort != null ? " - HTTPS " + httpsPort : ""));
}
- // private ExtendedHttpService waitForHttpService() {
- // final ServiceTracker<ExtendedHttpService, ExtendedHttpService> st = new
- // ServiceTracker<ExtendedHttpService, ExtendedHttpService>(
- // bc, ExtendedHttpService.class, null);
- // st.open();
- // ExtendedHttpService httpService;
- // try {
- // httpService = st.waitForService(1000);
- // } catch (InterruptedException e) {
- // httpService = null;
- // }
- //
- // if (httpService == null)
- // throw new CmsException("Could not find "
- // + ExtendedHttpService.class + " service.");
- // return httpService;
- // }
+ @Override
+ public Locale getDefaultLocale() {
+ return defaultLocale;
+ }
+
+ /** Can be null. */
+ @Override
+ public List<Locale> getLocales() {
+ return locales;
+ }
final private static void directorsCut(long initDuration) {
// final long ms = 128l + (long) (Math.random() * 128d);
final static String TRANSACTIONS_HOME = "argeo.node.transactions.home";
- final static String I18N_AVAILABLE_LOCALES = "argeo.i18n.availableLocales";
+ final static String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale";
+ final static String I18N_LOCALES = "argeo.i18n.locales";
// Node Security
final static String ROLES_URI = "argeo.node.roles.uri";
package org.argeo.cms.internal.kernel;
+import java.util.List;
+import java.util.Locale;
+
public interface KernelHeader {
+ public Locale getDefaultLocale();
+ public List<Locale> getLocales();
}
package org.argeo.cms.widgets.auth;
+import static org.argeo.cms.CmsMsg.password;
+import static org.argeo.cms.CmsMsg.username;
import static org.argeo.cms.auth.AuthConstants.LOGIN_CONTEXT_ANONYMOUS;
import static org.argeo.cms.auth.AuthConstants.LOGIN_CONTEXT_USER;
+import static org.argeo.cms.internal.kernel.Activator.getKernelHeader;
import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import org.argeo.cms.CmsView;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.HttpRequestCallback;
+import org.argeo.cms.i18n.Msg;
import org.argeo.cms.util.CmsUtils;
import org.argeo.util.LocaleChoice;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class CmsLogin implements CmsStyles, CallbackHandler {
- private Text username, password;
+ private Text usernameT, passwordT;
private Composite credentialsBlock;
+
+ private final Locale defaultLocale;
private LocaleChoice localeChoice = null;
private final CmsView cmsView;
public CmsLogin(CmsView cmsView) {
this.cmsView = cmsView;
+ defaultLocale = getKernelHeader().getDefaultLocale();
+ List<Locale> locales = getKernelHeader().getLocales();
+ if (locales != null)
+ localeChoice = new LocaleChoice(locales, defaultLocale);
}
protected boolean isAnonymous() {
parent.setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU);
// new Label(this, SWT.NONE).setText(CmsMsg.username.lead());
- username = new Text(credentialsBlock, SWT.BORDER);
- username.setMessage(CmsMsg.username.lead());
- username.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_USERNAME);
+ usernameT = new Text(credentialsBlock, SWT.BORDER);
+ usernameT.setMessage(username.lead(defaultLocale));
+ usernameT.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_USERNAME);
GridData gd = CmsUtils.fillWidth();
gd.widthHint = textWidth;
- username.setLayoutData(gd);
+ usernameT.setLayoutData(gd);
// new Label(this, SWT.NONE).setText(CmsMsg.password.lead());
- password = new Text(credentialsBlock, SWT.BORDER | SWT.PASSWORD);
- password.setMessage(CmsMsg.password.lead());
- password.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_PASSWORD);
+ passwordT = new Text(credentialsBlock, SWT.BORDER | SWT.PASSWORD);
+ passwordT.setMessage(password.lead(defaultLocale));
+ passwordT.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_PASSWORD);
gd = CmsUtils.fillWidth();
gd.widthHint = textWidth;
- password.setLayoutData(gd);
+ passwordT.setLayoutData(gd);
TraverseListener tl = new TraverseListener() {
private static final long serialVersionUID = -1158892811534971856L;
}
};
credentialsBlock.addTraverseListener(tl);
- username.addTraverseListener(tl);
- password.addTraverseListener(tl);
+ usernameT.addTraverseListener(tl);
+ passwordT.addTraverseListener(tl);
parent.setTabList(new Control[] { credentialsBlock });
- credentialsBlock.setTabList(new Control[] { username, password });
+ credentialsBlock.setTabList(new Control[] { usernameT, passwordT });
credentialsBlock.setFocus();
+
+ if (localeChoice != null)
+ createLocalesBlock(credentialsBlock);
return credentialsBlock;
}
+ protected Composite createLocalesBlock(final Composite parent) {
+ Composite c = new Composite(parent, SWT.NONE);
+ c.setLayout(CmsUtils.noSpaceGridLayout());
+ c.setLayoutData(CmsUtils.fillAll());
+
+ SelectionListener selectionListener = new SelectionAdapter() {
+ private static final long serialVersionUID = 4891637813567806762L;
+
+ public void widgetSelected(SelectionEvent event) {
+ localeChoice.setSelectedIndex((Integer) event.widget.getData());
+ Locale selectedLocale = localeChoice.getSelectedLocale();
+ usernameT.setMessage(username.lead(selectedLocale));
+ passwordT.setMessage(password.lead(selectedLocale));
+ };
+ };
+
+ List<Locale> locales = localeChoice.getLocales();
+ for (Integer i = 0; i < locales.size(); i++) {
+ Locale locale = locales.get(i);
+ Button button = new Button(c, SWT.RADIO);
+ button.setData(i);
+ button.setText(Msg.lead(locale.getDisplayName(locale), locale)
+ + " (" + locale + ")");
+ // button.addListener(SWT.Selection, listener);
+ button.addSelectionListener(selectionListener);
+ if (i == localeChoice.getDefaultIndex())
+ button.setSelection(true);
+ }
+ return c;
+ }
+
protected void login() {
Subject subject = cmsView.getSubject();
LoginContext loginContext;
UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback)
- ((NameCallback) callback).setName(username.getText());
+ ((NameCallback) callback).setName(usernameT.getText());
else if (callback instanceof PasswordCallback)
- ((PasswordCallback) callback).setPassword(password
+ ((PasswordCallback) callback).setPassword(passwordT
.getTextChars());
else if (callback instanceof HttpRequestCallback)
((HttpRequestCallback) callback).setRequest(RWT.getRequest());
--- /dev/null
+changePassword=Change password
\ No newline at end of file
--- /dev/null
+changePassword=Changer de mot de passe
\ No newline at end of file
source.. = src/
+bin.includes = OSGI-INF/
<command
id="org.argeo.security.ui.rap.openChangePasswordDialog"
defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
- name="Change Password">
+ name="%changePassword">
</command>
<!-- Enable an "open file" action in a single sourced application -->
<command
<command
commandId="org.argeo.security.ui.rap.openChangePasswordDialog"
icon="icons/password.gif"
- label="Change password"/>
+ label="%changePassword"/>
<separator
name="org.argeo.security.ui.rap.beforeFile"
visible="true">
import org.argeo.cms.auth.AuthConstants;
import org.argeo.cms.widgets.auth.DefaultLoginDialog;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.argeo.util.LocaleUtils;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.application.EntryPoint;
throw new ArgeoException("Login succeeded but no auth");// fatal
// add thread locale to RWT session
- if (log.isTraceEnabled())
- log.trace("Locale " + LocaleUtils.threadLocale.get());
- RWT.setLocale(LocaleUtils.threadLocale.get());
+ // if (log.isTraceEnabled())
+ // log.trace("Locale " + LocaleUtils.threadLocale.get());
+ // RWT.setLocale(LocaleUtils.threadLocale.get());
// once the user is logged in, longer session timeout
RWT.getRequest().getSession()
*/
package org.argeo.security.ui.commands;
+import static org.argeo.cms.CmsMsg.changePassword;
+import static org.argeo.cms.CmsMsg.currentPassword;
+import static org.argeo.cms.CmsMsg.newPassword;
+import static org.argeo.cms.CmsMsg.passwordChanged;
+import static org.argeo.cms.CmsMsg.repeatNewPassword;
+import static org.eclipse.jface.dialogs.IMessageProvider.INFORMATION;
+
import java.security.AccessController;
import javax.naming.InvalidNameException;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
HandlerUtil.getActiveShell(event), userAdmin);
if (dialog.open() == Dialog.OK) {
MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
- "Password changed", "Password changed.");
+ passwordChanged.lead(), passwordChanged.lead());
}
return null;
}
class ChangePasswordDialog extends TitleAreaDialog {
private static final long serialVersionUID = -6963970583882720962L;
- private Text currentPassword, newPassword1, newPassword2;
+ private Text oldPassword, newPassword1, newPassword2;
public ChangePasswordDialog(Shell parentShell, UserAdmin securityService) {
super(parentShell);
composite.setLayout(new GridLayout(2, false));
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
false));
- currentPassword = createLP(composite, "Current password");
- newPassword1 = createLP(composite, "New password");
- newPassword2 = createLP(composite, "Repeat new password");
+ oldPassword = createLP(composite, currentPassword.lead());
+ newPassword1 = createLP(composite, newPassword.lead());
+ newPassword2 = createLP(composite, repeatNewPassword.lead());
- setMessage("Change password", IMessageProvider.INFORMATION);
+ setMessage(changePassword.lead(), INFORMATION);
parent.pack();
return composite;
}
if (!newPassword1.getText().equals(newPassword2.getText()))
throw new ArgeoException("Passwords are different");
try {
- changePassword(currentPassword.getTextChars(),
+ changePassword(oldPassword.getTextChars(),
newPassword1.getTextChars());
close();
} catch (Exception e) {
protected void configureShell(Shell shell) {
super.configureShell(shell);
- shell.setText("Change password");
+ shell.setText(changePassword.lead());
}
}
package org.argeo.util;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.security.auth.callback.LanguageCallback;
+import org.argeo.ArgeoException;
+
/** Choose in a list of locales. TODO: replace with {@link LanguageCallback} */
public class LocaleChoice {
- private List<Locale> availableLocales = new ArrayList<Locale>();
+ private final List<Locale> locales;
private Integer selectedIndex = null;
- private Integer defaultIndex = null;
+ private final Integer defaultIndex;
+
+ public LocaleChoice(List<Locale> locales, Locale defaultLocale) {
+ Integer defaultIndex = null;
+ this.locales = Collections.unmodifiableList(locales);
+ for (int i = 0; i < locales.size(); i++)
+ if (locales.get(i).equals(defaultLocale))
+ defaultIndex = i;
- // public LocaleCallback(Integer defaultIndex, List<Locale>
- // availableLocales) {
- // this.availableLocales = Collections
- // .unmodifiableList(new ArrayList<Locale>(availableLocales));
- // this.defaultIndex = defaultIndex;
- // this.selectedIndex = defaultIndex;
- // }
+ // based on language only
+ if (defaultIndex == null)
+ for (int i = 0; i < locales.size(); i++)
+ if (locales.get(i).getLanguage()
+ .equals(defaultLocale.getLanguage()))
+ defaultIndex = i;
+
+ if (defaultIndex == null)
+ throw new ArgeoException("Default locale " + defaultLocale
+ + " is not in available locales " + locales);
+ this.defaultIndex = defaultIndex;
+
+ this.selectedIndex = defaultIndex;
+ }
/**
* Convenience constructor based on a comma separated list of iso codes (en,
* en_US, fr_CA, etc.). Default selection is default locale.
*/
public LocaleChoice(String locales, Locale defaultLocale) {
- if (locales == null || locales.trim().equals(""))
- return;
- String[] codes = locales.split(",");
- for (int i = 0; i < codes.length; i++) {
- String code = codes[i];
- // variant not supported
- int indexUnd = code.indexOf("_");
- Locale locale;
- if (indexUnd > 0) {
- String language = code.substring(0, indexUnd);
- String country = code.substring(indexUnd + 1);
- locale = new Locale(language, country);
- } else {
- locale = new Locale(code);
- }
- availableLocales.add(locale);
- if (locale.equals(defaultLocale))
- defaultIndex = i;
- }
-
- if (defaultIndex == null)
- defaultIndex = 0;
-
- this.selectedIndex = defaultIndex;
+ this(asLocaleList(locales), defaultLocale);
}
public String[] getSupportedLocalesLabels() {
- String[] labels = new String[availableLocales.size()];
- for (int i = 0; i < availableLocales.size(); i++) {
- Locale locale = availableLocales.get(i);
+ String[] labels = new String[locales.size()];
+ for (int i = 0; i < locales.size(); i++) {
+ Locale locale = locales.get(i);
if (locale.getCountry().equals(""))
labels[i] = locale.getDisplayLanguage(locale) + " ["
+ locale.getLanguage() + "]";
public Locale getSelectedLocale() {
if (selectedIndex == null)
return null;
- return availableLocales.get(selectedIndex);
+ return locales.get(selectedIndex);
}
public void setSelectedIndex(Integer selectedIndex) {
return defaultIndex;
}
- public List<Locale> getAvailableLocales() {
- return availableLocales;
+ public List<Locale> getLocales() {
+ return locales;
}
public Locale getDefaultLocale() {
- return availableLocales.get(getDefaultIndex());
+ return locales.get(getDefaultIndex());
+ }
+
+ /** Returns null if argument is null. */
+ public static List<Locale> asLocaleList(String locales) {
+ if (locales == null)
+ return null;
+ ArrayList<Locale> availableLocales = new ArrayList<Locale>();
+ String[] codes = locales.split(",");
+ for (int i = 0; i < codes.length; i++) {
+ String code = codes[i];
+ // variant not supported
+ int indexUnd = code.indexOf("_");
+ Locale locale;
+ if (indexUnd > 0) {
+ String language = code.substring(0, indexUnd);
+ String country = code.substring(indexUnd + 1);
+ locale = new Locale(language, country);
+ } else {
+ locale = new Locale(code);
+ }
+ availableLocales.add(locale);
+ }
+ return availableLocales;
}
public static void main(String[] args) {
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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 org.argeo.util;
-
-import java.util.Locale;
-
-import org.argeo.ArgeoException;
-
-/** Utilities around internationalization. */
-public class LocaleUtils {
- /**
- * The locale of the current thread and its children. Allows to deal with
- * internationalisation as a cross cutting aspect. Never null.
- */
- public final static InheritableThreadLocal<Locale> threadLocale = new InheritableThreadLocal<Locale>() {
- @Override
- protected Locale initialValue() {
- return Locale.getDefault();
- }
-
- @Override
- public void set(Locale value) {
- if (value == null)
- throw new ArgeoException("Thread local cannot be null.");
- super.set(value);
- }
-
- };
-}