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-94f89814c4dfmaster
parent
c432218345
commit
083bb6d34e
|
|
@ -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();
|
||||
languageCodes.add( loc.getLanguage());
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -308,6 +308,6 @@ public class Date extends Widget implements BebopConstants {
|
|||
}
|
||||
|
||||
// Don't lock
|
||||
@Override
|
||||
public void lock() {}
|
||||
// @Override
|
||||
// public void lock() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|||
* ...
|
||||
* </bebop:*select></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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,23 +154,20 @@ 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,
|
||||
String val) {
|
||||
String val) {
|
||||
req.setAttribute(DISPATCHER_PREFIX_ATTR, val);
|
||||
}
|
||||
|
||||
|
|
@ -185,15 +179,14 @@ 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);
|
||||
}
|
||||
|
||||
private static void forwardHelper(javax.servlet.RequestDispatcher rd,
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
|
||||
Object attr = req.getAttribute(INCLUDE_URI);
|
||||
|
||||
|
|
@ -237,10 +230,10 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* propagated from target resource
|
||||
*/
|
||||
public static void forwardRequestByPath(String path,
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp,
|
||||
ServletContext sctx)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp,
|
||||
ServletContext sctx)
|
||||
throws IOException, ServletException {
|
||||
RequestDispatcher rd = sctx.getRequestDispatcher(path);
|
||||
forwardHelper(rd, req, resp);
|
||||
}
|
||||
|
|
@ -250,11 +243,11 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* DispatcherHelper.getRequestContext(req).getServletContext())</code>.
|
||||
*/
|
||||
public static void forwardRequestByPath(String path,
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp)
|
||||
throws IOException, ServletException {
|
||||
ServletContext sctx =
|
||||
DispatcherHelper.getRequestContext(req).getServletContext();
|
||||
DispatcherHelper.getRequestContext(req).getServletContext();
|
||||
forwardRequestByPath(path, req, resp, sctx);
|
||||
}
|
||||
|
||||
|
|
@ -277,8 +270,8 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* propagated from target resource
|
||||
*/
|
||||
public static void forwardRequestByPath(String path,
|
||||
PageContext pageContext)
|
||||
throws IOException, ServletException {
|
||||
PageContext pageContext)
|
||||
throws IOException, ServletException {
|
||||
|
||||
ServletRequest req = pageContext.getRequest();
|
||||
Object attr = req.getAttribute(INCLUDE_URI);
|
||||
|
|
@ -311,10 +304,10 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* propagated from target resource
|
||||
*/
|
||||
public static void forwardRequestByName(String name,
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp,
|
||||
ServletContext sctx)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp,
|
||||
ServletContext sctx)
|
||||
throws IOException, ServletException {
|
||||
RequestDispatcher rd = sctx.getNamedDispatcher(name);
|
||||
forwardHelper(rd, req, resp);
|
||||
}
|
||||
|
|
@ -324,9 +317,9 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* DispatcherHelper.getRequestContext(req).getServletContext())</code>.
|
||||
*/
|
||||
public static void forwardRequestByName(String name,
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest req,
|
||||
HttpServletResponse resp)
|
||||
throws IOException, ServletException {
|
||||
ServletContext sc = getRequestContext(req).getServletContext();
|
||||
forwardRequestByName(name, req, resp, sc);
|
||||
}
|
||||
|
|
@ -355,12 +348,12 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* extensions when your file on disk has an extension.
|
||||
*/
|
||||
public static String resolveAbstractFile(File abstractFile,
|
||||
RequestContext actx)
|
||||
throws RedirectException, DirectoryListingException,
|
||||
java.io.FileNotFoundException {
|
||||
RequestContext actx)
|
||||
throws RedirectException, DirectoryListingException,
|
||||
java.io.FileNotFoundException {
|
||||
s_log.debug("Resolving abstract file");
|
||||
|
||||
File dirToSearch = null;
|
||||
File dirToSearch = null;
|
||||
String fStr = abstractFile.getAbsolutePath();
|
||||
int lastSlash = fStr.lastIndexOf(File.separatorChar);
|
||||
String filenameStub = fStr.substring(lastSlash + 1);
|
||||
|
|
@ -392,13 +385,13 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
for (int j = 0; j < extensionSearchList.length; j++) {
|
||||
|
||||
File possibleFile =
|
||||
new File(dirToSearch,
|
||||
filenameStub + extensionSearchList[j]);
|
||||
new File(dirToSearch,
|
||||
filenameStub + extensionSearchList[j]);
|
||||
|
||||
for (int i = 0; i < filesInDir.length; i++) {
|
||||
if (filesInDir[i].equals(possibleFile)) {
|
||||
return (indexPage ? File.separator + "index" : "")
|
||||
+ extensionSearchList[j];
|
||||
+ extensionSearchList[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -485,34 +475,34 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* or restore the original wrapper if it was already wrapped.
|
||||
*/
|
||||
public static HttpServletRequest maybeWrapRequest(HttpServletRequest sreq)
|
||||
throws IOException, ServletException {
|
||||
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);
|
||||
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);
|
||||
orig);
|
||||
|
||||
DispatcherHelper.saveOriginalRequest(sreq,
|
||||
orig);
|
||||
orig);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -534,7 +524,7 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param oldReq the original servlet request
|
||||
*/
|
||||
public static void saveOriginalRequest(HttpServletRequest req,
|
||||
HttpServletRequest oldReq) {
|
||||
HttpServletRequest oldReq) {
|
||||
req.setAttribute(ORIGINAL_REQUEST_ATTR, oldReq);
|
||||
}
|
||||
|
||||
|
|
@ -552,8 +542,8 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param url the destination URL for redirect
|
||||
**/
|
||||
public static void sendRedirect(HttpServletResponse resp,
|
||||
String url)
|
||||
throws IOException {
|
||||
String url)
|
||||
throws IOException {
|
||||
sendExternalRedirect(resp, url);
|
||||
}
|
||||
|
||||
|
|
@ -567,8 +557,8 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param url the destination URL for redirect
|
||||
**/
|
||||
public static void sendRedirect(HttpServletRequest req,
|
||||
HttpServletResponse resp,
|
||||
String url)
|
||||
HttpServletResponse resp,
|
||||
String url)
|
||||
throws IOException {
|
||||
sendExternalRedirect(resp, url);
|
||||
}
|
||||
|
|
@ -581,7 +571,7 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param url the destination URL for redirect
|
||||
**/
|
||||
public static void sendExternalRedirect(HttpServletResponse resp,
|
||||
String url)
|
||||
String url)
|
||||
throws IOException {
|
||||
if (s_log.isDebugEnabled()) {
|
||||
s_log.debug("Redirecting to URL '" + url + "'", new Throwable());
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -720,8 +708,8 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @see com.arsdigita.util.URLRewriter
|
||||
**/
|
||||
public static String encodeURL(HttpServletRequest req,
|
||||
HttpServletResponse resp,
|
||||
String url) {
|
||||
HttpServletResponse resp,
|
||||
String url) {
|
||||
return URLRewriter.encodeURL(req, resp, url);
|
||||
}
|
||||
|
||||
|
|
@ -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,14 +855,14 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -883,23 +870,26 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
*/
|
||||
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,8 +903,9 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -933,9 +924,10 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param maxage the max time in second until this expires
|
||||
*/
|
||||
public static void maybeCacheForUser(HttpServletResponse response,
|
||||
int maxage) {
|
||||
if (!response.containsHeader("Cache-Control"))
|
||||
int maxage) {
|
||||
if (!response.containsHeader("Cache-Control")) {
|
||||
cacheForUser(response, maxage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -945,9 +937,10 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param expiry the time at which to expire
|
||||
*/
|
||||
public static void maybeCacheForUser(HttpServletResponse response,
|
||||
Date expiry) {
|
||||
if (!response.containsHeader("Cache-Control"))
|
||||
Date expiry) {
|
||||
if (!response.containsHeader("Cache-Control")) {
|
||||
cacheForUser(response, expiry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -957,13 +950,14 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param maxage the max life of the response in seconds
|
||||
*/
|
||||
public static void cacheForUser(HttpServletResponse response,
|
||||
int maxage) {
|
||||
int maxage) {
|
||||
init();
|
||||
if (!s_cachingActive)
|
||||
if (!s_cachingActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.isTrue(!response.containsHeader("Cache-Control"),
|
||||
"Caching headers have already been set");
|
||||
"Caching headers have already been set");
|
||||
|
||||
s_log.info("Setting cache control to user");
|
||||
|
||||
|
|
@ -986,8 +980,8 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param expiry time at which to expire
|
||||
*/
|
||||
public static void cacheForUser(HttpServletResponse response,
|
||||
Date expiry) {
|
||||
cacheForUser(response, (int)((expiry.getTime() - (new Date()).getTime()) / 1000l));
|
||||
Date expiry) {
|
||||
cacheForUser(response, (int) ((expiry.getTime() - (new Date()).getTime()) / 1000l));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -997,8 +991,9 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1017,12 +1012,12 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param maxage the time in seconds until expiry
|
||||
*/
|
||||
public static void maybeCacheForWorld(HttpServletResponse response,
|
||||
int maxage) {
|
||||
if (!response.containsHeader("Cache-Control"))
|
||||
int maxage) {
|
||||
if (!response.containsHeader("Cache-Control")) {
|
||||
cacheForWorld(response, maxage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If no existing cache policy is set, then
|
||||
* call cacheForUser to enable caching for
|
||||
|
|
@ -1030,9 +1025,10 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param expiry the time at which it will expire
|
||||
*/
|
||||
public static void maybeCacheForWorld(HttpServletResponse response,
|
||||
Date expiry) {
|
||||
if (!response.containsHeader("Cache-Control"))
|
||||
Date expiry) {
|
||||
if (!response.containsHeader("Cache-Control")) {
|
||||
cacheForWorld(response, expiry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1042,33 +1038,33 @@ public final class DispatcherHelper implements DispatcherConstants {
|
|||
* @param maxage time in seconds until this expires
|
||||
*/
|
||||
public static void cacheForWorld(HttpServletResponse response,
|
||||
int maxage) {
|
||||
int maxage) {
|
||||
init();
|
||||
if (!s_cachingActive)
|
||||
if (!s_cachingActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.isTrue(!response.containsHeader("Cache-Control"),
|
||||
"Caching headers have already been set");
|
||||
"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);
|
||||
response.setHeader("Expires",
|
||||
rfc1123_formatter.format(expires.getTime()));
|
||||
rfc1123_formatter.format(expires.getTime()));
|
||||
response.setHeader("Last-Modified",
|
||||
rfc1123_formatter.format(new Date()));
|
||||
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));
|
||||
Date expiry) {
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue