Verbesserungen an der Mehrsprachenfähigkeit

* Die Konfigurations-Parameter waf.categorization.supported_languages und com.arsdigita.cms.languages zu waf.kernel.supported_languages zusammengefasst
 * In DispatcherHelper eine Methode getNegotiatedLocale eingeführt, die beim Aushandeln der Locale zwischen Browser und CCM auch dem Konfigurations-Parameter waf.kernel.supported_languages respektiert
 * Alle Aufrufe von DispatcherHelper.getRequest().getLocale() auf die neue Methode DispatcherHelper.getNegotiatedLocale() geändert.
 * Konfiguration von Categorization geändert. Verwendet jetzt keinen eigenen Eintrag für die unterstützten Sprachen mehr. Stattdessen wird die Konfiguration von Kernel verwendet.
 * ContentSectionInitializer geändert, so daß er nun Kernel.getConfig().getSupportedLanguages() verwendet.


Außerdem diverse Aufräumarbeiten (Unnötige Imports entfernt, Reformat, Annotationen hinzugefügt, Klammern bei If-Anweisungen) in den Sourcen, wo immer sie mir in die Händegefallen sind.

git-svn-id: https://svn.libreccm.org/ccm/trunk@419 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2010-05-14 10:18:30 +00:00
parent c432218345
commit 083bb6d34e
23 changed files with 320 additions and 311 deletions

View File

@ -22,6 +22,7 @@ import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryCollection;
import com.arsdigita.cms.lifecycle.Lifecycle;
import com.arsdigita.cms.lifecycle.LifecycleDefinition;
import com.arsdigita.cms.util.LanguageUtil;
import com.arsdigita.domain.AbstractDomainObjectObserver;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObject;
@ -406,8 +407,12 @@ public class ContentBundle extends ContentItem {
* <code>locales</code>
* @pre locales != null
*/
// Quasimodo:
// Is this method ever used? Netbeans couldn't find anything.
public ContentItem negotiate(Locale[] locales) {
Assert.exists(locales);
String supportedLanguages = LanguageUtil.getSupportedLanguages();
DataAssociationCursor instancesCursor = instances();
DataObject dataObject = null;
int bestMatch = 0;
@ -417,6 +422,11 @@ public class ContentBundle extends ContentItem {
dataObject = instancesCursor.getDataObject();
language = (String) dataObject.get(LANGUAGE);
// If language is not one of the supported languages, skip this entry
if(!supportedLanguages.contains(language)) {
continue;
}
if (s_log.isDebugEnabled()) {
s_log.debug("negotiate: language= " + language);
}
@ -462,6 +472,8 @@ public class ContentBundle extends ContentItem {
* @pre locales != null
*/
public ContentItem negotiate(Enumeration locales) {
String supportedLanguages = LanguageUtil.getSupportedLanguages();
Assert.exists(locales);
/* copy "locales" enumeration, since we have to iterate
* over it several times
@ -470,7 +482,12 @@ public class ContentBundle extends ContentItem {
List languageCodes = new ArrayList();
for (int i = 0; locales.hasMoreElements(); i++) {
loc = (Locale)locales.nextElement();
// Quasimodo:
// Only add languages to the List which are supported by cms
if(supportedLanguages.contains(loc.getLanguage())) {
languageCodes.add( loc.getLanguage());
}
if (s_log.isDebugEnabled()) {
s_log.debug("negotiate: pref " + i + ": "+ loc.getLanguage());
}

View File

@ -37,43 +37,20 @@ import com.arsdigita.cms.dispatcher.ItemResolver;
import com.arsdigita.cms.dispatcher.MultilingualItemResolver;
import com.arsdigita.cms.dispatcher.TemplateResolver;
import com.arsdigita.cms.lifecycle.PublishLifecycleListener;
// import com.arsdigita.cms.publishToFile.PublishToFile;
import com.arsdigita.cms.publishToFile.PublishToFileConfig;
// import com.arsdigita.cms.publishToFile.PublishToFileListener;
import com.arsdigita.cms.ui.authoring.ItemCategoryExtension;
import com.arsdigita.cms.ui.authoring.ItemCategoryForm;
import com.arsdigita.runtime.AbstractConfig;
// URL resource: protocol handler removal: START
// remove
// import com.arsdigita.util.UncheckedWrapperException;
// URL resource: protocol handler removal: END
import com.arsdigita.util.parameter.BooleanParameter;
// import com.arsdigita.util.parameter.ClassParameter;
import com.arsdigita.util.parameter.EnumerationParameter;
import com.arsdigita.util.parameter.ErrorList;
import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.Parameter;
// import com.arsdigita.util.parameter.ParameterError;
// URL resource: protocol handler removal: START
// new: import:
import com.arsdigita.util.parameter.ResourceParameter;
// URL resource: protocol handler removal: END
import com.arsdigita.util.parameter.SpecificClassParameter;
import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter;
// URL resource: protocol handler removal: START
// remove:
// import com.arsdigita.util.parameter.URLParameter;
// new: import:
import com.arsdigita.util.StringUtils;
// URL resource: protocol handler removal: END
// URL resource: protocol handler removal: START
// remove:
// import java.io.IOException;
// import java.net.MalformedURLException;
// import java.net.URL;
// URL resource: protocol handler removal: END
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
@ -107,7 +84,6 @@ public final class ContentSectionConfig extends AbstractConfig {
private final Parameter m_defaultItemTemplatePath;
private final Parameter m_defaultFolderTemplatePath;
private final Parameter m_defaultSection;
private final Parameter m_languages;
private final Parameter m_defaultItemResolverClass;
private final Parameter m_defaultTemplateResolverClass;
private final Parameter m_useSectionCategories;
@ -171,9 +147,6 @@ public final class ContentSectionConfig extends AbstractConfig {
m_defaultFolderTemplatePath = new StringParameter
("com.arsdigita.cms.default_folder_template_path",
Parameter.REQUIRED, "/default/folder.jsp");
m_languages = new StringParameter
("com.arsdigita.cms.languages",
Parameter.REQUIRED, "en,de,fr,nl,it,pt,es");
m_linksOnlyInSameSubsite = new BooleanParameter
("com.arsdigita.cms.browse_links_in_same_subsite_only",
@ -427,7 +400,6 @@ public final class ContentSectionConfig extends AbstractConfig {
register(m_templateRootPath);
register(m_defaultItemTemplatePath);
register(m_defaultFolderTemplatePath);
register(m_languages);
register(m_defaultItemResolverClass);
register(m_defaultTemplateResolverClass);
register(m_categoryAuthoringAddForm);
@ -491,10 +463,6 @@ public final class ContentSectionConfig extends AbstractConfig {
return (String) get(m_defaultFolderTemplatePath);
}
public final String getLanguages() {
return (String) get(m_languages);
}
public final Class getDefaultItemResolverClass() {
return (Class) get(m_defaultItemResolverClass);
}

View File

@ -13,11 +13,6 @@ com.arsdigita.cms.default_folder_template_path.purpose=Path for the default fold
com.arsdigita.cms.default_folder_template_path.example=/default/folder.jsp
com.arsdigita.cms.default_folder_template_path.format=[string]
com.arsdigita.cms.languages.title=Languages
com.arsdigita.cms.languages.purpose=The list of languages for this installation.
com.arsdigita.cms.languages.example=en,de,fr,nl,it,pt,es
com.arsdigita.cms.languages.format=[string]
com.arsdigita.cms.default_item_resolver_class.title=Item resolver class
com.arsdigita.cms.default_item_resolver_class.purpose=Default item resolver class will be used for any content section which does not override in SectionInitializer enterprise.init section. This class must implement com.arsdigita.cms.dispatcher.ItemResolver.
com.arsdigita.cms.default_item_resolver_class.example=com.arsdigita.cms.dispatcher.MultilingualItemResolver

View File

@ -78,6 +78,7 @@ import com.arsdigita.xml.XML;
import com.arsdigita.templating.PatternStylesheetResolver;
import com.arsdigita.cms.util.LanguageUtil;
import com.arsdigita.kernel.Kernel;
/**
* The CMS initializer.
@ -110,10 +111,11 @@ public class Initializer extends CompoundInitializer {
* This starts up the search threads according to the values in the
* properties file
*/
@Override
public void init(DomainInitEvent e) {
super.init(e);
LanguageUtil.setSupportedLanguages(
ContentSection.getConfig().getLanguages());
Kernel.getConfig().getSupportedLanguages());
URLService.registerFinder(ContentPage.BASE_DATA_OBJECT_TYPE,
new ItemURLFinder());

View File

@ -88,9 +88,11 @@ public abstract class ContentTypeInitializer extends CompoundInitializer {
*
* @param evt Type of initialization
*/
@Override
public void init(DomainInitEvent evt) {
super.init(evt);
// Register an optional traversal adapter for the content type
final String traversal = getTraversalXML();
if (!StringUtils.emptyString(traversal)) {
XML.parseResource
@ -98,6 +100,7 @@ public abstract class ContentTypeInitializer extends CompoundInitializer {
new TraversalHandler());
}
// Load and register stylesheets for the content type
try {
ContentType type = ContentType.findByAssociatedObjectType(m_objectType);

View File

@ -32,7 +32,6 @@ import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.categorization.CategorizationConfig;
import com.arsdigita.categorization.CategorizedCollection;
import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryCollection;
@ -46,6 +45,7 @@ import com.arsdigita.cms.ui.VisibilityComponent;
import com.arsdigita.cms.ui.permissions.CMSPermissionsPane;
import com.arsdigita.cms.ui.templates.CategoryTemplates;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.User;
import com.arsdigita.kernel.permissions.ObjectPermissionCollection;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
@ -100,6 +100,7 @@ class CategoryItemPane extends BaseItemPane {
final ActionLink orderItemsLink = new ActionLink(new Label(
gz("cms.ui.category.categorized_objects"))) {
@Override
public boolean isVisible(PageState state) {
// update for live items only
if (!super.isVisible(state)) {
@ -139,10 +140,11 @@ class CategoryItemPane extends BaseItemPane {
// Localizations
ActionLink addCategoryLocalizationLink = new ActionLink(new Label(gz(
"cms.ui.category.localization.add"))) {
@Override
public boolean isVisible(PageState state) {
// Only show addLanguage button, if there are langauges to add
int countSupportedLanguages = (
new CategorizationConfig()).getSupportedLanguages()
Kernel.getConfig()).getSupportedLanguagesTokenizer()
.countTokens();
long countLanguages =
m_category.getCategory(state)
@ -198,6 +200,7 @@ class CategoryItemPane extends BaseItemPane {
super(child, null);
}
@Override
public boolean hasPermission(PageState ps) {
return m_category.getCategory(ps).canEdit();
}
@ -208,6 +211,7 @@ class CategoryItemPane extends BaseItemPane {
super(child, null);
}
@Override
public boolean hasPermission(PageState ps) {
return m_category.getCategory(ps).canAdmin();
}
@ -258,6 +262,7 @@ class CategoryItemPane extends BaseItemPane {
}
private class Properties extends PropertyList {
@Override
protected final java.util.List properties(final PageState state) {
final java.util.List props = super.properties(state);
final Category category = m_category.getCategory(state);
@ -363,6 +368,7 @@ class CategoryItemPane extends BaseItemPane {
group.addAction(new EditVisible(linkAddLink), ActionGroup.EDIT);
}
@Override
public final boolean isVisible(final PageState state) {
return !m_category.getCategory(state).isRoot();
}
@ -382,6 +388,7 @@ class CategoryItemPane extends BaseItemPane {
}
private class PermissionsSection extends Section {
@Override
public boolean isVisible(PageState ps) {
Category cat = m_category.getCategory(ps);
return !cat.isRoot() && cat.canAdmin();
@ -408,6 +415,7 @@ class CategoryItemPane extends BaseItemPane {
final CMSPermissionsPane permPane = new CMSPermissionsPane
(privs, privMap, new ACSObjectSelectionModel(m_model)) {
@Override
public void showAdmin(PageState ps) {
Assert.exists(m_model.getSelectedKey(ps));
@ -418,6 +426,7 @@ class CategoryItemPane extends BaseItemPane {
final ActionLink restoreDefault = new ActionLink(new Label(gz(
"cms.ui.restore_default_permissions"))) {
@Override
public boolean isVisible(PageState ps) {
Category cat = m_category.getCategory(ps);
return PermissionService.getContext(cat) == null;
@ -426,6 +435,7 @@ class CategoryItemPane extends BaseItemPane {
final ActionLink useCustom = new ActionLink(new Label(gz(
"cms.ui.use_custom_permissions"))) {
@Override
public boolean isVisible(PageState ps) {
Category cat = m_category.getCategory(ps);
return PermissionService.getContext(cat) != null;
@ -513,6 +523,7 @@ class CategoryItemPane extends BaseItemPane {
// Build the preview link. This uses a standard redirect link to find
// the content. The prepareURL method is called by the printwriter
@Override
protected String prepareURL(final PageState state, String location) {
ContentItem indexItem = ((ContentBundle)(m_category.getCategory(state)
@ -526,6 +537,7 @@ class CategoryItemPane extends BaseItemPane {
}
// We only show this link when an index item exists for this category
@Override
public boolean isVisible(PageState state) {
if (!super.isVisible(state)) {
return false;

View File

@ -26,10 +26,11 @@ import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.categorization.CategorizationConfig;
import com.arsdigita.categorization.Category;
import com.arsdigita.dispatcher.AccessDeniedException;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.KernelConfig;
import java.util.Locale;
import java.util.StringTokenizer;
@ -78,8 +79,8 @@ public class CategoryLocalizationAddForm extends CategoryLocalizationForm {
"cms.ui.select_one").localize())), state);
// all supported languages (by registry entry)
CategorizationConfig catConfig = new CategorizationConfig();
StringTokenizer strTok = catConfig.getSupportedLanguages();
KernelConfig kernelConfig = Kernel.getConfig();
StringTokenizer strTok = kernelConfig.getSupportedLanguagesTokenizer();
while(strTok.hasMoreTokens()) {

View File

@ -64,7 +64,6 @@ public class LanguageUtil {
*/
public static void setSupportedLanguages(String languages) {
s_languages = languages;
// initializeLanguageRanks(getSupportedLanguages());
}
/** Get the comma separated list of all supported languages */

View File

@ -308,6 +308,6 @@ public class Date extends Widget implements BebopConstants {
}
// Don't lock
@Override
public void lock() {}
// @Override
// public void lock() {}
}

View File

@ -73,6 +73,7 @@ public abstract class OptionGroup extends Widget
// request-local copy of selected elements, options
private RequestLocal m_requestOptions = new RequestLocal() {
@Override
public Object initialValue(PageState ps) {
return new ArrayList();
}
@ -233,11 +234,16 @@ public abstract class OptionGroup extends Widget
if( null != m_form ) {
m_otherOption.setForm( m_form );
if( m_isDisabled ) m_otherOption.setDisabled();
if( m_isReadOnly ) m_otherOption.setReadOnly();
if( m_isDisabled ) {
m_otherOption.setDisabled();
}
if( m_isReadOnly ) {
m_otherOption.setReadOnly();
}
}
setParameterModel( new ParameterModelWrapper( model ) {
@Override
public ParameterData createParameterData( final HttpServletRequest request,
Object defaultValue,
boolean isSubmission ) {
@ -251,21 +257,24 @@ public abstract class OptionGroup extends Widget
if( null != values ) {
for( int i = 0; i < values.length; i++ ) {
if( OTHER_OPTION.equals( values[i] ) )
if( OTHER_OPTION.equals( values[i] ) ) {
values[i] = other;
}
}
}
s_log.debug( "createParameterData in OptionGroup" );
return super.createParameterData( new HttpServletRequestWrapper( request ) {
@Override
public String[] getParameterValues( String key ) {
if( s_log.isDebugEnabled() ) {
s_log.debug( "Getting values for " + key );
}
if( model.getName().equals( key ) )
if( model.getName().equals( key ) ) {
return values;
}
return super.getParameterValues( key );
}
}, defaultValue, isSubmission );
@ -301,6 +310,7 @@ public abstract class OptionGroup extends Widget
setOptionSelected(option.getValue());
}
@Override
public Object clone() throws CloneNotSupportedException {
OptionGroup cloned = (OptionGroup)super.clone();
cloned.m_options = (ArrayList) m_options.clone();
@ -323,25 +333,34 @@ public abstract class OptionGroup extends Widget
return true;
}
@Override
public void setDisabled() {
m_isDisabled = true;
if( null != m_otherOption ) m_otherOption.setDisabled();
if( null != m_otherOption ) {
m_otherOption.setDisabled();
}
super.setDisabled();
}
@Override
public void setReadOnly() {
m_isReadOnly = true;
if( null != m_otherOption ) m_otherOption.setReadOnly();
if( null != m_otherOption ) {
m_otherOption.setReadOnly();
}
super.setReadOnly();
}
@Override
public void setForm( Form form ) {
m_form = form;
if( null != m_otherOption ) m_otherOption.setForm( form );
if( null != m_otherOption ) {
m_otherOption.setForm(form);
}
super.setForm( form );
}
@ -354,6 +373,7 @@ public abstract class OptionGroup extends Widget
* ...
* &lt;/bebop:*select&gt;</code></pre>
*/
@Override
public void generateWidget( PageState state, Element parent ) {
Element optionGroup =
parent.newChildElement( getElementTag(), BEBOP_XML_NS );
@ -368,7 +388,8 @@ public abstract class OptionGroup extends Widget
o.generateXML( state, optionGroup );
}
if( null != m_otherOption )
m_otherOption.generateXML( state, optionGroup );
if( null != m_otherOption ) {
m_otherOption.generateXML(state, optionGroup);
}
}
}

View File

@ -40,7 +40,6 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.text.SimpleDateFormat;
@ -49,7 +48,6 @@ import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -169,7 +167,7 @@ public class PageTransformer implements PresentationManager {
("negotiated-language",
new XSLParameterGenerator() {
public String generateValue(HttpServletRequest request) {
return com.arsdigita.dispatcher.DispatcherHelper.getRequestContext().getLocale().getLanguage();
return DispatcherHelper.getNegotiatedLocale().getLanguage();
}
});
}

View File

@ -32,6 +32,7 @@ public interface BebopConstants {
String BEBOP_CHECKBOX = "bebop:checkbox";
String BEBOP_DATE = "bebop:date";
String BEBOP_DATETIME = "bebop:datetime";
String BEBOP_TIME = "bebop:time";
String BEBOP_MULTISELECT = "bebop:multiSelect";
String BEBOP_OPTION = "bebop:option";
String BEBOP_RADIOGROUP = "bebop:radioGroup";

View File

@ -19,24 +19,11 @@
package com.arsdigita.categorization;
import com.arsdigita.runtime.AbstractConfig;
// unused imports
// import com.arsdigita.runtime.RuntimeConfig;
// import com.arsdigita.util.Assert;
import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.StringParameter;
// import com.arsdigita.util.parameter.ErrorList;
// import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.Parameter;
// import com.arsdigita.util.parameter.ParameterError;
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
// import java.util.Map;
// import java.util.HashMap;
// import java.util.Set;
// import java.util.HashSet;
/**
* Stores the configuration record for the Categorization functionality.
*
@ -48,7 +35,6 @@ public final class CategorizationConfig extends AbstractConfig {
private static Logger s_log = Logger.getLogger(CategorizationConfig.class);
private final Parameter m_showInternalName;
private final Parameter m_supportedLanguages;
/**
* Public Constructor
@ -68,17 +54,7 @@ public final class CategorizationConfig extends AbstractConfig {
Parameter.REQUIRED,
new Boolean(true));
/**
* String containing the supported languages. The first one is considered
* as default.
*/
m_supportedLanguages = new StringParameter
("waf.categorization.supported_languages",
Parameter.REQUIRED,
"en,de,fr");
register(m_showInternalName);
register(m_supportedLanguages);
loadInfo();
}
@ -89,26 +65,4 @@ public final class CategorizationConfig extends AbstractConfig {
public final boolean getShowInternalName() {
return ((Boolean) get(m_showInternalName)).booleanValue();
}
/**
* Returns the defaultLanguage flag.
*/
public final String getDefaultLanguage() {
return ((String) get(m_supportedLanguages)).trim().substring(0, 2);
}
/**
* Returns the supportedLanguages as StringTokenizer.
*/
public final StringTokenizer getSupportedLanguages() {
return new StringTokenizer((String) get(m_supportedLanguages), ",", false);
}
/**
* Return true, if language lang is part of supported langs
*/
public final boolean hasLanguage(String lang) {
return ((String) get(m_supportedLanguages)).contains(lang);
}
}

View File

@ -2,7 +2,3 @@ waf.categorization.show_internal_name.title=Activate output of internal keys (la
waf.categorization.show_internal_name.purpose=Activate it to output internal keys for categories without the requested locale. This is usually for debugging. It is set to true here to preserve backwards compatibility to version 1.0.4 and prior.
waf.categorization.show_internal_name.example=true
waf.categorization.show_internal_name.format=[boolean]
waf.categorization.supported_languages.title=Set the supported languages for categorization
waf.categorization.supported_languages.purpose=Set the supported languages for categorization. First entry is the default language
waf.categorization.supported_languages.example=en,de,fr
waf.categorization.supported_languages.format=[string]

View File

@ -19,6 +19,7 @@
package com.arsdigita.categorization;
import com.arsdigita.db.Sequences;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.domain.DomainServiceInterfaceExposer;
import com.arsdigita.kernel.ACSObject;
@ -361,6 +362,7 @@ public class Category extends ACSObject {
/**
* @see com.arsdigita.domain.DomainObject#initialize()
*/
@Override
protected void initialize() {
super.initialize();
@ -415,7 +417,7 @@ public class Category extends ACSObject {
* @return the category name.
*/
public String getName() {
return getName(this.getNegotiatedLocale());
return getName(DispatcherHelper.getNegotiatedLocale().getLanguage());
}
/**
@ -432,6 +434,7 @@ public class Category extends ACSObject {
* implementation.
* @return the category name.
*/
@Override
public String getDisplayName() {
return getName();
}
@ -588,7 +591,7 @@ public class Category extends ACSObject {
* @return the category name.
*/
public String getDescription() {
return getDescription(this.getNegotiatedLocale());
return getDescription(DispatcherHelper.getNegotiatedLocale().getLanguage());
}
/**
@ -656,7 +659,7 @@ public class Category extends ACSObject {
* @return URL component used when browsing categories
*/
public String getURL() {
return getURL(this.getNegotiatedLocale());
return getURL(DispatcherHelper.getNegotiatedLocale().getLanguage());
}
@ -730,7 +733,7 @@ public class Category extends ACSObject {
* otherwise.
*/
public boolean isEnabled() {
return isEnabled(this.getNegotiatedLocale());
return isEnabled(DispatcherHelper.getNegotiatedLocale().getLanguage());
}
/**
@ -2202,42 +2205,6 @@ public class Category extends ACSObject {
}
// Quasimodo: Begin
/**
* Getting the negotiated locale from requestContext
* @return the negotiated language string if in supported lang list or default language else
*/
private String getNegotiatedLocale() {
String locale = null;
try {
// Try to get locale from request context
locale = com.arsdigita.dispatcher.DispatcherHelper.getRequestContext().getLocale().getLanguage();
} catch(NullPointerException ex) {
// If there is no request context (ex. during ccm setup) use default language
locale = Category.getConfig().getDefaultLanguage();
} finally {
// if supported lang contains locale
if(Category.getConfig().hasLanguage(locale)) {
// then return locale
return locale;
} else {
// else return default language
return Category.getConfig().getDefaultLanguage();
}
}
}
public CategoryLocalizationCollection getCategoryLocalizationCollection() {
return m_categoryLocalizationCollection;
}

View File

@ -18,7 +18,8 @@
*/
package com.arsdigita.dispatcher;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.util.Assert;
import com.arsdigita.util.ParameterProvider;
import com.arsdigita.util.StringUtils;
@ -33,6 +34,8 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
@ -56,24 +59,20 @@ import org.apache.log4j.Logger;
* @version $Id: DispatcherHelper.java 311 2005-02-28 11:10:00Z mbooth $
* @since 4.5 */
public final class DispatcherHelper implements DispatcherConstants {
private static final Logger s_log = Logger.getLogger
(DispatcherHelper.class);
private static final Logger s_log = Logger.getLogger(DispatcherHelper.class);
private static String s_webappCtx;
private static String s_staticURL;
private static boolean s_cachingActive;
private static int s_defaultExpiry;
private static DispatcherConfig s_config;
public static SimpleDateFormat rfc1123_formatter;
private static boolean initialized = false;
static void init() {
if (initialized)
if (initialized) {
return;
}
rfc1123_formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
rfc1123_formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
@ -86,15 +85,14 @@ public final class DispatcherHelper implements DispatcherConstants {
initialized = true;
}
/**
* The current HttpServletRequest.
*/
private static ThreadLocal s_request = new ThreadLocal();
/** null constructor, private so no one can instantiate! */
private DispatcherHelper() { }
private DispatcherHelper() {
}
/**
* Return default cache expiry.
@ -132,9 +130,8 @@ public final class DispatcherHelper implements DispatcherConstants {
* @return the URL path (relative to the webapp root) for the currently
* executing resource.
*/
public static String getCurrentResourcePath
(HttpServletRequest req) {
String attr = (String)req.getAttribute(INCLUDE_URI);
public static String getCurrentResourcePath(HttpServletRequest req) {
String attr = (String) req.getAttribute(INCLUDE_URI);
String str;
if (attr == null) {
str = req.getRequestURI();
@ -157,19 +154,16 @@ public final class DispatcherHelper implements DispatcherConstants {
* Gets the application context from the request attributes.
* @return the application context from the request attributes.
*/
public static RequestContext getRequestContext
(HttpServletRequest req) {
return (RequestContext)req.getAttribute(REQUEST_CONTEXT_ATTR);
public static RequestContext getRequestContext(HttpServletRequest req) {
return (RequestContext) req.getAttribute(REQUEST_CONTEXT_ATTR);
}
public static RequestContext getRequestContext() {
return (RequestContext) getRequest().getAttribute(REQUEST_CONTEXT_ATTR);
}
public static String getDispatcherPrefix
(HttpServletRequest req) {
return (String)req.getAttribute(DISPATCHER_PREFIX_ATTR);
public static String getDispatcherPrefix(HttpServletRequest req) {
return (String) req.getAttribute(DISPATCHER_PREFIX_ATTR);
}
public static void setDispatcherPrefix(HttpServletRequest req,
@ -185,8 +179,7 @@ public final class DispatcherHelper implements DispatcherConstants {
* @param ac the current request context
* @post DispatcherHelper.getRequestContext(req) == ac
*/
public static void setRequestContext
(HttpServletRequest req, RequestContext ac) {
public static void setRequestContext(HttpServletRequest req, RequestContext ac) {
req.setAttribute(REQUEST_CONTEXT_ATTR, ac);
}
@ -447,11 +440,9 @@ public final class DispatcherHelper implements DispatcherConstants {
* @return the original servlet request object, as created by
* the servlet container. This can be used as a parameter for forward().
*/
public static HttpServletRequest restoreOriginalRequest
(HttpServletRequest req) {
public static HttpServletRequest restoreOriginalRequest(HttpServletRequest req) {
if (req instanceof MultipartHttpServletRequest) {
HttpServletRequest oldReq = (HttpServletRequest)
req.getAttribute(ORIGINAL_REQUEST_ATTR);
HttpServletRequest oldReq = (HttpServletRequest) req.getAttribute(ORIGINAL_REQUEST_ATTR);
oldReq.setAttribute(WRAPPED_REQUEST_ATTR, req);
req = oldReq;
}
@ -468,14 +459,13 @@ public final class DispatcherHelper implements DispatcherConstants {
* request, if any;
* otherwise returns the request object.
*/
public static HttpServletRequest restoreRequestWrapper
(HttpServletRequest req) {
public static HttpServletRequest restoreRequestWrapper(HttpServletRequest req) {
// switch back wrapped request if we're forwarded
// from somewhere else.
Object maybeWrappedReq = req.getAttribute(WRAPPED_REQUEST_ATTR);
if (maybeWrappedReq != null &&
!(req instanceof MultipartHttpServletRequest)) {
req = (HttpServletRequest)maybeWrappedReq;
if (maybeWrappedReq != null
&& !(req instanceof MultipartHttpServletRequest)) {
req = (HttpServletRequest) maybeWrappedReq;
}
return req;
}
@ -488,20 +478,20 @@ public final class DispatcherHelper implements DispatcherConstants {
throws IOException, ServletException {
final String type = sreq.getContentType();
if (sreq.getMethod().toUpperCase().equals("POST") &&
type != null &&
type.toLowerCase().startsWith("multipart")) {
if (sreq.getMethod().toUpperCase().equals("POST")
&& type != null
&& type.toLowerCase().startsWith("multipart")) {
final HttpServletRequest orig = sreq;
final HttpServletRequest previous =
DispatcherHelper.restoreRequestWrapper(orig);
if (previous instanceof MultipartHttpServletRequest) {
s_log.debug("Build new multipart request from previous " +
previous + " and current " + orig);
s_log.debug("Build new multipart request from previous "
+ previous + " and current " + orig);
MultipartHttpServletRequest previousmp =
(MultipartHttpServletRequest)previous;
(MultipartHttpServletRequest) previous;
sreq = new MultipartHttpServletRequest(previousmp,
orig);
@ -511,8 +501,8 @@ public final class DispatcherHelper implements DispatcherConstants {
s_log.debug("The main request is now " + sreq);
} else {
s_log.debug("The request is a new multipart; wrapping the request " +
"object");
s_log.debug("The request is a new multipart; wrapping the request "
+ "object");
try {
sreq = new MultipartHttpServletRequest(sreq);
} catch (MessagingException me) {
@ -522,8 +512,8 @@ public final class DispatcherHelper implements DispatcherConstants {
DispatcherHelper.saveOriginalRequest(sreq, orig);
}
} else {
s_log.debug("The request is not multipart; proceeding " +
"without wrapping the request");
s_log.debug("The request is not multipart; proceeding "
+ "without wrapping the request");
}
return sreq;
}
@ -599,10 +589,9 @@ public final class DispatcherHelper implements DispatcherConstants {
HttpServletRequest req = getRequest();
Object attr;
if (req != null &&
(attr = req.getAttribute(REENTRANCE_ATTRIBUTE)) != null) {
req.getSession(true).setAttribute
(REDIRECT_SEMAPHORE, attr);
if (req != null
&& (attr = req.getAttribute(REENTRANCE_ATTRIBUTE)) != null) {
req.getSession(true).setAttribute(REDIRECT_SEMAPHORE, attr);
}
if (url.startsWith("http")) {
@ -624,20 +613,19 @@ public final class DispatcherHelper implements DispatcherConstants {
s_log.debug("Setting destination to " + destination);
}
} else {
final ParameterMap params = ParameterMap.fromString
(url.substring(sep + 1));
final ParameterMap params = ParameterMap.fromString(url.substring(sep + 1));
destination = URL.there(req, url.substring(0, sep), params);
if (s_log.isDebugEnabled()) {
s_log.debug("Setting destination with map to " +
destination);
s_log.debug("Setting destination with map to "
+ destination);
}
}
throw new RedirectSignal(destination, true);
} else {
if (s_log.isDebugEnabled()) {
s_log.debug("Redirecting to URL without using URL.there. " +
"URL is " + url);
s_log.debug("Redirecting to URL without using URL.there. "
+ "URL is " + url);
}
throw new RedirectSignal(url, true);
}
@ -798,27 +786,27 @@ public final class DispatcherHelper implements DispatcherConstants {
init();
String webappCtx = null;
HttpServletRequest request = DispatcherHelper.getRequest();
if ( request != null ) {
if (request != null) {
webappCtx = request.getContextPath();
// Safety check to make sure the webappCtx from the request
// matches the webappCtx from enterprise.init.
if ( s_webappCtx != null ) {
if ( s_webappCtx.equals("/") ) {
if (s_webappCtx != null) {
if (s_webappCtx.equals("/")) {
s_webappCtx = "";
}
if ( !s_webappCtx.equals(webappCtx) ) {
if (!s_webappCtx.equals(webappCtx)) {
s_log.warn(
"webappContext changed. Expected='" + s_webappCtx +
"' found='" + webappCtx + "'.\nPerhaps the enterprise.init " +
"com.arsdigita.dispatcher.Initializer webappContext " +
"parameter is wrong.");
"webappContext changed. Expected='" + s_webappCtx
+ "' found='" + webappCtx + "'.\nPerhaps the enterprise.init "
+ "com.arsdigita.dispatcher.Initializer webappContext "
+ "parameter is wrong.");
// Save the webappCtx from the request for future use.
s_webappCtx = webappCtx;
}
}
} else {
if ( s_webappCtx != null && s_webappCtx.equals("/") ) {
if (s_webappCtx != null && s_webappCtx.equals("/")) {
s_webappCtx = "";
}
webappCtx = s_webappCtx;
@ -858,7 +846,6 @@ public final class DispatcherHelper implements DispatcherConstants {
return (HttpServletRequest) s_request.get();
}
/***************************************************/
/* !!! Danger Will Robinson!!!! */
/* */
@ -868,38 +855,41 @@ public final class DispatcherHelper implements DispatcherConstants {
/* */
/* -- Daniel Berrange <berrange@redhat.com> */
/***************************************************/
/**
* If no existing cache policy is set, then call
* cacheDisable to disable all caching of the response.
*/
public static void maybeCacheDisable(HttpServletResponse response) {
if (!response.containsHeader("Cache-Control"))
if (!response.containsHeader("Cache-Control")) {
cacheDisable(response);
}
}
/**
* Aggressively disable all caching of the response
*/
public static void cacheDisable(HttpServletResponse response) {
init();
if (!s_cachingActive)
if (!s_cachingActive) {
return;
}
// Assert.isTrue(!response.containsHeader("Cache-Control"),
// "Caching headers have already been set");
// XXX Probably need to assert here if isCommitted() returns true.
// But first need to figure out what is setting Cache-Control.
if (response.containsHeader("Cache-Control"))
if (response.containsHeader("Cache-Control")) {
s_log.warn("Cache-Control has already been set. Overwriting.");
}
forceCacheDisable(response);
}
public static void forceCacheDisable(HttpServletResponse response) {
init();
if (!s_cachingActive)
if (!s_cachingActive) {
return;
}
s_log.info("Setting cache control to disable");
// Aggressively defeat caching - works even for HTTP 0.9 proxies/clients!
@ -913,9 +903,10 @@ public final class DispatcherHelper implements DispatcherConstants {
* call cacheForUser to enable caching for a user
*/
public static void maybeCacheForUser(HttpServletResponse response) {
if (!response.containsHeader("Cache-Control"))
if (!response.containsHeader("Cache-Control")) {
cacheForUser(response);
}
}
/**
* Allow caching of the response for this user only,
@ -934,9 +925,10 @@ public final class DispatcherHelper implements DispatcherConstants {
*/
public static void maybeCacheForUser(HttpServletResponse response,
int maxage) {
if (!response.containsHeader("Cache-Control"))
if (!response.containsHeader("Cache-Control")) {
cacheForUser(response, maxage);
}
}
/**
* If no existing cache policy is set, then
@ -946,9 +938,10 @@ public final class DispatcherHelper implements DispatcherConstants {
*/
public static void maybeCacheForUser(HttpServletResponse response,
Date expiry) {
if (!response.containsHeader("Cache-Control"))
if (!response.containsHeader("Cache-Control")) {
cacheForUser(response, expiry);
}
}
/**
* Allow caching of the response for this user only,
@ -959,8 +952,9 @@ public final class DispatcherHelper implements DispatcherConstants {
public static void cacheForUser(HttpServletResponse response,
int maxage) {
init();
if (!s_cachingActive)
if (!s_cachingActive) {
return;
}
Assert.isTrue(!response.containsHeader("Cache-Control"),
"Caching headers have already been set");
@ -987,7 +981,7 @@ public final class DispatcherHelper implements DispatcherConstants {
*/
public static void cacheForUser(HttpServletResponse response,
Date expiry) {
cacheForUser(response, (int)((expiry.getTime() - (new Date()).getTime()) / 1000l));
cacheForUser(response, (int) ((expiry.getTime() - (new Date()).getTime()) / 1000l));
}
/**
@ -997,9 +991,10 @@ public final class DispatcherHelper implements DispatcherConstants {
* the default age setting
*/
public static void maybeCacheForWorld(HttpServletResponse response) {
if (!response.containsHeader("Cache-Control"))
if (!response.containsHeader("Cache-Control")) {
cacheForWorld(response);
}
}
/**
* Allow caching of this response for anyone in the
@ -1018,10 +1013,10 @@ public final class DispatcherHelper implements DispatcherConstants {
*/
public static void maybeCacheForWorld(HttpServletResponse response,
int maxage) {
if (!response.containsHeader("Cache-Control"))
if (!response.containsHeader("Cache-Control")) {
cacheForWorld(response, maxage);
}
}
/**
* If no existing cache policy is set, then
@ -1031,9 +1026,10 @@ public final class DispatcherHelper implements DispatcherConstants {
*/
public static void maybeCacheForWorld(HttpServletResponse response,
Date expiry) {
if (!response.containsHeader("Cache-Control"))
if (!response.containsHeader("Cache-Control")) {
cacheForWorld(response, expiry);
}
}
/**
* Allow caching of this response for anyone in the
@ -1044,14 +1040,15 @@ public final class DispatcherHelper implements DispatcherConstants {
public static void cacheForWorld(HttpServletResponse response,
int maxage) {
init();
if (!s_cachingActive)
if (!s_cachingActive) {
return;
}
Assert.isTrue(!response.containsHeader("Cache-Control"),
"Caching headers have already been set");
Calendar expires = Calendar.getInstance();
expires.add( Calendar.SECOND, maxage );
expires.add(Calendar.SECOND, maxage);
s_log.info("Setting cache control to world");
response.setHeader("Cache-Control", "public, max-age=" + maxage);
@ -1061,14 +1058,13 @@ public final class DispatcherHelper implements DispatcherConstants {
rfc1123_formatter.format(new Date()));
}
/**
* Allow caching of this response for anyone in the world.
* THe response will expire at the time given.
*/
public static void cacheForWorld(HttpServletResponse response,
Date expiry) {
cacheForWorld(response, (int)((expiry.getTime() - (new Date()).getTime()) / 1000l));
cacheForWorld(response, (int) ((expiry.getTime() - (new Date()).getTime()) / 1000l));
}
/**
@ -1081,4 +1077,48 @@ public final class DispatcherHelper implements DispatcherConstants {
}
return s_config;
}
/**
* This method returns the best matching locate for the request. In contrast to
* the other methods available this one will also respect the supported_languages
* config entry.
*
* @return The negotiated locale
*/
public static Locale getNegotiatedLocale() {
KernelConfig kernelConfig = Kernel.getConfig();
// Set the preferedLocale to the default locale (first entry in the config parameter list)
Locale preferedLocale = new Locale(kernelConfig.getDefaultLanguage(), "", "");
// The ACCEPTED_LANGUAGES from the client
Enumeration locales = null;
// Try to get the RequestContext
try {
locales = ((ServletRequest) DispatcherHelper.getRequest()).getLocales();
// For everey element in the enumerator
while (locales.hasMoreElements()) {
// Test if the current locale is listed in the supported locales list
Locale curLocale = (Locale) locales.nextElement();
if (kernelConfig.hasLanguage(curLocale.getLanguage())) {
preferedLocale = curLocale;
break;
}
}
} catch (NullPointerException ex) {
// Don't have to do anything because I want to fall back to default language anyway
// This case should only appear during setup
} finally {
return preferedLocale;
}
}
}

View File

@ -361,7 +361,7 @@ public class DomainObjectXMLRenderer extends DomainObjectTraversal {
// Quasimodo: BEGIN
// Add attributes for date and time
Locale negLocale = com.arsdigita.dispatcher.DispatcherHelper.getRequestContext().getLocale();
Locale negLocale = com.arsdigita.dispatcher.DispatcherHelper.getNegotiatedLocale();
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.MEDIUM, negLocale);
DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.SHORT, negLocale);
element.addAttribute("date", dateFormatter.format(date));

View File

@ -74,6 +74,7 @@ public abstract class OptionEditor extends FormSection {
// Only create the Option Group once per request
private RequestLocal m_optionGroup =
new RequestLocal() {
@Override
public Object initialValue(PageState pageState) {
BigDecimal control = (BigDecimal)m_control.getSelectedKey(pageState);

View File

@ -20,7 +20,6 @@ package com.arsdigita.installer;
import com.arsdigita.util.UncheckedWrapperException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@ -51,8 +50,12 @@ public abstract class SQLLoader {
public static void load(final Connection conn,
final String script) {
if (conn == null) throw new IllegalArgumentException();
if (script == null) throw new IllegalArgumentException();
if (conn == null) {
throw new IllegalArgumentException();
}
if (script == null) {
throw new IllegalArgumentException();
}
final SQLLoader loader = new SQLLoader(conn) {
protected final Reader open(final String name) {

View File

@ -70,11 +70,7 @@ public class Kernel {
s_securityConfig = new SecurityConfig();
s_initialContext.setLocale(Locale.getDefault());
// deprecated, use load() instead which loads ccm-core/kernel.properties
// by default for KernelConfig / SecurityConfig
// s_config.load("ccm-core/kernel.properties");
s_config.load();
// s_securityConfig.load("ccm-core/security.properties");
s_securityConfig.load();
s_context = new ThreadLocal() {
public Object initialValue() {

View File

@ -22,6 +22,8 @@ import com.arsdigita.runtime.AbstractConfig;
import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.EnumerationParameter;
import com.arsdigita.util.parameter.Parameter;
import com.arsdigita.util.parameter.StringParameter;
import java.util.StringTokenizer;
/**
* @author Justin Ross
@ -36,6 +38,7 @@ public final class KernelConfig extends AbstractConfig {
private final Parameter m_SSO;
private final Parameter m_remember;
private final Parameter m_secureLogin;
private final Parameter m_supportedLanguages;
public KernelConfig() {
m_debug = new BooleanParameter
@ -60,12 +63,20 @@ public final class KernelConfig extends AbstractConfig {
m_secureLogin = new BooleanParameter
("waf.kernel.secure_login", Parameter.REQUIRED, Boolean.FALSE);
/**
* String containing the supported languages. The first one is considered
* default.
*/
m_supportedLanguages = new StringParameter
("waf.kernel.supported_languages", Parameter.REQUIRED, "en,de,fr,nl,it,pt,es");
register(m_debug);
register(m_permissions);
register(m_identifier);
register(m_SSO);
register(m_remember);
register(m_secureLogin);
register(m_supportedLanguages);
loadInfo();
}
@ -111,4 +122,33 @@ public final class KernelConfig extends AbstractConfig {
public static final boolean isPermissionCheckEnabled() {
return Kernel.getConfig().isDataPermissionCheckEnabled();
}
/**
* Returns the defaultLanguage flag.
*/
public final String getDefaultLanguage() {
return ((String) get(m_supportedLanguages)).trim().substring(0, 2);
}
/**
* Returns the supportedLanguages as String.
*/
public final String getSupportedLanguages() {
return (String) get(m_supportedLanguages);
}
/**
* Returns the supportedLanguages as StringTokenizer.
*/
public final StringTokenizer getSupportedLanguagesTokenizer() {
return new StringTokenizer(this.getSupportedLanguages(), ",", false);
}
/**
* Return true, if language lang is part of supported langs
*/
public final boolean hasLanguage(String lang) {
return ((String) get(m_supportedLanguages)).contains(lang);
}
}

View File

@ -22,3 +22,7 @@ waf.kernel.sso_login.title=Enable SSO login
waf.kernel.sso_login.purpose=Enable alternative "RegisterSSO" login context.
waf.kernel.sso_login.example=false
waf.kernel.sso_login.format=true|false
waf.kernel.supported_languages.title=Set the supported languages for categorization
waf.kernel.supported_languages.purpose=Set the supported languages for categorization. First entry is the default language
waf.kernel.supported_languages.example=en,de,fr,nl,it,pt,es
waf.kernel.supported_languages.format=[string]

View File

@ -19,7 +19,6 @@
package com.arsdigita.london.navigation.ui;
import com.arsdigita.categorization.Category;
import com.arsdigita.london.navigation.DataCollectionDefinition;
import com.arsdigita.london.navigation.DataCollectionRenderer;
@ -67,6 +66,7 @@ public abstract class AbstractObjectList
return m_definition.getDataCollection(getModel());
}
@Override
public void lock() {
super.lock();
m_renderer.lock();
@ -96,16 +96,7 @@ public abstract class AbstractObjectList
// Quasimodo: Begin
// Limit list to objects in the negotiated language
if (objects != null && objects.size() > 0) {
String locale = com.arsdigita.dispatcher.DispatcherHelper.getRequestContext().getLocale().getLanguage();
// if supported lang doesn't contain locale
if(!Category.getConfig().hasLanguage(locale)) {
// use default language instead
locale = Category.getConfig().getDefaultLanguage();
}
objects.addEqualsFilter("language", locale);
objects.addEqualsFilter("language", com.arsdigita.dispatcher.DispatcherHelper.getNegotiatedLocale().getLanguage());
}
// Quasimodo: End