Sprachunabhängige ContentItems

* ContentBundle#negotiate() ist nun deprecated
 * ContentBundle#getInstance() und ContentBundle#hasInstance() haben nun einen optionalen Parameter allowLanguageIndependent
 * Alle Aufrufe von ContentBundle#negotiate() in GlobalizationHelper#getNegotiatedLocale(), true) geändert

Bekannte Probleme:

 * AbstractObjectList: Zeigt zur Zeit auf Grund eines falschen SQL-Filters ggf. ein CI zweimal an (als Sprachvariante und als sprachunabhängige Variante)
* die Aufrufe von ContentBundle#getInstance() und ContentBundle#hasInstance() haben zur Zeit u.U. ein fest programmierten Parameter true. Dieser Parameter muß später als genereller Config-Parameter gesetzt werden, so daß man das Feature der sprachunabhängigen ContentItems bei Bedarf abschalten kann.

git-svn-id: https://svn.libreccm.org/ccm/trunk@1162 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2011-10-13 06:55:40 +00:00
parent ad84f95434
commit 7129f9af5f
10 changed files with 96 additions and 60 deletions

View File

@ -2,9 +2,9 @@ package com.arsdigita.cms.contentassets;
import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.contenttypes.LinkTraversalAdapter;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.domain.DomainObject;
import com.arsdigita.domain.SimpleDomainObjectTraversalAdapter;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.persistence.metadata.Property;
/**
@ -35,8 +35,8 @@ public class RelatedLinkTraversalAdapter extends LinkTraversalAdapter {
if (obj instanceof ContentBundle) {
nObj = ((ContentBundle) obj).negotiate(DispatcherHelper.getRequest().
getLocales());
nObj = ((ContentBundle) obj).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
}
if (nObj instanceof RelatedLink) {

View File

@ -28,6 +28,7 @@ import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObject;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.domain.DomainObjectObserver;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.persistence.DataAssociation;
import com.arsdigita.persistence.DataAssociationCursor;
@ -280,6 +281,14 @@ public class ContentBundle extends ContentItem {
return new ItemCollection(instances());
}
public final ContentItem getInstance(final Locale locale) {
return this.getInstance(locale.getLanguage(), false);
}
public final ContentItem getInstance(final Locale locale, boolean allowLanguageIndependent) {
return this.getInstance(locale.getLanguage(), allowLanguageIndependent);
}
/**
* Returns a language instance for <code>language</code> or
* <code>null</code> if no such instance exists.
@ -288,6 +297,10 @@ public class ContentBundle extends ContentItem {
* it only returns an exact match for the given Locale or
* <code>null</code> if no such match is found.
*
* It will try to return a language independent version of the
* content item, if there is one and {@code allowLanguageIndependent}
* is true.
*
* @param language the language for which to get an instance
* @return the instance of this item which exactly matches the
* <em>language</em> part of the Locale <code>l</code>
@ -295,6 +308,10 @@ public class ContentBundle extends ContentItem {
* @pre language != null
*/
public final ContentItem getInstance(final String language) {
return this.getInstance(language, false);
}
public final ContentItem getInstance(final String language, boolean allowLanguageIndependent) {
if (Assert.isEnabled()) {
Assert.exists(language, String.class);
Assert.isTrue(language.length() == 2,
@ -302,43 +319,28 @@ public class ContentBundle extends ContentItem {
+ "code");
}
// The data object to return
ContentItem contentItem = null;
// Try to get the content item in the exact language
DataAssociationCursor instances = instances();
instances.addEqualsFilter(LANGUAGE, language);
DataObject dataObject = null;
if (instances.next()) {
final DataObject data = instances.getDataObject();
if (Assert.isEnabled()) {
//Assert.isFalse(instances.next(),
// "There is more than one instance with the " +
// "same language");
contentItem = (ContentItem) DomainObjectFactory.newInstance(instances.getDataObject());
;
}
instances.close();
return (ContentItem) DomainObjectFactory.newInstance(data);
} else {
instances.close();
// Look for language invariant version
instances = instances();
instances.addEqualsFilter(LANGUAGE, "--");
if (instances.next()) {
final DataObject data = instances.getDataObject();
instances.close();
return (ContentItem) DomainObjectFactory.newInstance(data);
} else {
instances.close();
// Try to get a language independent version of the content item,
// if we couldn't find an exact match and language independent
// content items are acceptable.
if (contentItem == null && allowLanguageIndependent == true) {
contentItem = this.getInstance("--", false);
}
return null;
}
return contentItem;
}
/**
@ -366,19 +368,33 @@ public class ContentBundle extends ContentItem {
* @see ContentItem#getLanguage()
*/
public final boolean hasInstance(final String language) {
return this.hasInstance(language, false);
}
public final boolean hasInstance(final String language, boolean allowLanguageIndependent) {
if (Assert.isEnabled()) {
Assert.exists(language, String.class);
Assert.isTrue(language.length() == 2,
language + " is not an ISO639 language code");
}
boolean retVal = false;
final DataAssociationCursor instances = instances();
// instances.addEqualsFilter(LANGUAGE, language);
// If allowLanguageIndependent == false (default case), only search
// for an exact language match
if (allowLanguageIndependent == false) {
instances.addEqualsFilter(LANGUAGE, language);
} // Else, search also for language independent version
else {
FilterFactory ff = instances.getFilterFactory();
Filter filter = ff.or().
addFilter(ff.equals("language", language)).
addFilter(ff.equals("language", "--"));
instances.addFilter(filter);
instances.addFilter(
ff.or().addFilter(ff.equals(LANGUAGE, language)).
addFilter(ff.equals(LANGUAGE, "--")));
}
return !instances.isEmpty();
}
@ -420,9 +436,13 @@ public class ContentBundle extends ContentItem {
* if there is no language instance for any of the locales in
* <code>locales</code>
* @pre locales != null
* @deprecated Locale negotiation takes place in
* {@link com.arsdigita.globalization.GlobalizationHelper}.
* Use {@link #getInstance(java.lang.String)} instead.
*/
// Quasimodo:
// Is this method ever used? Netbeans couldn't find anything.
@Deprecated
public ContentItem negotiate(Locale[] locales) {
Assert.exists(locales);
String supportedLanguages = LanguageUtil.getSupportedLanguages();
@ -445,7 +465,7 @@ public class ContentBundle extends ContentItem {
}
if (language != null) {
// If the current object is languange invariant and no better
// If the current object is languange independent and no better
// match is already found, match it with the lowest priority
if (language.equals("--") && matchingInstance == null) {
bestMatch = locales.length;
@ -490,7 +510,11 @@ public class ContentBundle extends ContentItem {
* @return the negotiated language instance or <code>null</code> if there
* is no language instance for any of the locales in <code>locales</code>.
* @pre locales != null
* @deprecated Locale negotiation takes place in
* {@link com.arsdigita.globalization.GlobalizationHelper}.
* Use {@link #getInstance(java.lang.String)} instead.
*/
@Deprecated
public ContentItem negotiate(Enumeration locales) {
String supportedLanguages = LanguageUtil.getSupportedLanguages();
@ -514,7 +538,7 @@ public class ContentBundle extends ContentItem {
}
}
// Add unspecified language for language invariant objects
// Add unspecified language for language independent objects
if (supportedLanguages.contains("--")) {
languageCodes.add("--");
}

View File

@ -53,8 +53,8 @@ public class ContentItemXMLRenderer extends DomainObjectXMLRenderer {
if (nObj instanceof ContentBundle) {
nObj = ((ContentBundle) obj).negotiate(DispatcherHelper.getRequest().
getLocales());
nObj = ((ContentBundle) obj).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
}
super.walk(adapter, nObj, path, context, linkObject);

View File

@ -24,6 +24,7 @@ import com.arsdigita.domain.DomainObject;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.domain.DomainObjectTraversalAdapter;
import com.arsdigita.domain.DomainObjectXMLRenderer;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.persistence.DataAssociation;
import com.arsdigita.persistence.DataAssociationCursor;
@ -128,8 +129,8 @@ public class CustomizableContentItemXMLRenderer
if (nObj instanceof ContentBundle) {
nObj = ((ContentBundle) obj).negotiate(DispatcherHelper.getRequest().
getLocales());
nObj = ((ContentBundle) obj).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
}

View File

@ -26,6 +26,7 @@ import com.arsdigita.cms.dispatcher.ItemResolver;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.DataOperation;
@ -213,8 +214,8 @@ public class Link extends ACSObject {
if (DispatcherHelper.getRequest() == null) {
ci = ((ContentBundle) acsObject).getPrimaryInstance();
} else {
ci = ((ContentBundle) acsObject).negotiate(DispatcherHelper.
getRequest().getLocales());
ci = ((ContentBundle) acsObject).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
}
} else {
// else there are no language versions so just use the acsObject

View File

@ -19,11 +19,11 @@
package com.arsdigita.cms.contenttypes;
import com.arsdigita.cms.ContentBundle;
import com.arsdigita.dispatcher.DispatcherHelper;
import org.apache.log4j.Logger;
import com.arsdigita.persistence.metadata.Property;
import com.arsdigita.domain.SimpleDomainObjectTraversalAdapter;
import com.arsdigita.domain.DomainObject;
import com.arsdigita.globalization.GlobalizationHelper;
/**
* An adapter for Links allowing pluggable
@ -66,8 +66,8 @@ public class LinkTraversalAdapter
s_log.debug(
"Found a link to a content bundle. Resolve this link to negotiated language.");
nObj = ((ContentBundle) obj).negotiate(DispatcherHelper.getRequest().
getLocales());
nObj = ((ContentBundle) obj).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
}
return super.processProperty(nObj, path, prop, context);

View File

@ -26,6 +26,7 @@ import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.dispatcher.SimpleXMLGenerator;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.cms.ContentItemXMLRenderer;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.xml.Element;
@ -140,7 +141,8 @@ public class ContentList extends AbstractComponent {
/*Fix by Quasimodo*/
/* getPrimaryInstance doesn't negotiate the language of the content item */
/* ContentItem cIndexItem = ((ContentBundle) indexItem).getPrimaryInstance().getLiveVersion(); */
ContentItem cItem = ((ContentBundle) indexItem).negotiate(request.getLocales());
ContentItem cItem = ((ContentBundle) indexItem).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
// If there is no matching language version for this content item
if(cItem == null) {
// get the primary instance instead (fallback)
@ -176,7 +178,8 @@ public class ContentList extends AbstractComponent {
/*Fix by Quasimodo*/
/* getPrimaryInstance doesn't negotiate the language of the content item */
/* ContentItem cIndexItem = ((ContentBundle) indexItem).getPrimaryInstance().getLiveVersion(); */
ContentItem cItem = ((ContentBundle) indexItem).negotiate(request.getLocales());
ContentItem cItem = ((ContentBundle) indexItem).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
// If there is no matching language version for this content item
if(cItem == null) {
// get the primary instance instead (fallback)
@ -264,7 +267,8 @@ public class ContentList extends AbstractComponent {
/*Fix by Quasimodo*/
/* getPrimaryInstance doesn't negotiate the language of the content item */
/* item = ((ContentBundle) item).getPrimaryInstance(); */
item = ((ContentBundle) item).negotiate(DispatcherHelper.getRequest().getLocales());
item = ((ContentBundle) item).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
// If there is no matching language version for this content item
if(item == null) {
// get the primary instance instead (fallback)

View File

@ -21,7 +21,7 @@ import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ExtraXMLGenerator;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.london.navigation.Navigation;
import com.arsdigita.xml.Element;
@ -111,7 +111,8 @@ public class GreetingItemExtraXML extends AbstractComponent {
/*Fix by Quasimodo*/
/* getPrimaryInstance doesn't negotiate the language of the content item */
/* ContentItem baseItem = bundle.getPrimaryInstance(); */
ContentItem baseItem = bundle.negotiate(DispatcherHelper.getRequest().getLocales());
ContentItem baseItem = bundle.
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
// If there is no matching language version for this content item
if(baseItem == null) {
// get the primary instance instead (fallback)

View File

@ -23,6 +23,7 @@ import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentItemXMLRenderer;
import com.arsdigita.cms.dispatcher.SimpleXMLGenerator;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.london.navigation.Navigation;
import com.arsdigita.xml.Element;
@ -65,7 +66,9 @@ public class NavigationRootIndexItem extends AbstractComponent {
/*Fix by Quasimodo*/
/* getPrimaryInstance doesn't negotiate the language of the content item */
/* ContentItem indexItem = ((ContentBundle) Navigation.getConfig().getDefaultCategoryRoot().getIndexObject()).getPrimaryInstance().getLiveVersion(); */
ContentItem indexItem = ((ContentBundle) Navigation.getConfig().getDefaultCategoryRoot().getIndexObject()).negotiate(request.getLocales());
ContentItem indexItem = ((ContentBundle) Navigation.getConfig().
getDefaultCategoryRoot().getIndexObject()).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
// if there is no matching language version for this content item
if(indexItem == null) {
// get the primary instance instead (fallback)

View File

@ -23,6 +23,7 @@ import com.arsdigita.london.navigation.RelatedItemsQueryFactory;
import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentPage;
import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.xml.Element;
@ -66,7 +67,8 @@ public class RelatedItems extends AbstractComponent {
/*Fix by Quasimodo*/
/* getPrimaryInstance doesn't negotiate the language of the content item */
/* obj = ((ContentBundle) obj).getPrimaryInstance(); */
ContentItem cItem = ((ContentBundle) obj).negotiate(request.getLocales());
ContentItem cItem = ((ContentBundle) obj).
getInstance(GlobalizationHelper.getNegotiatedLocale(), true);
// if there is no matching language version of the content item
if(cItem == null) {
// get the primary instance instead (fallback)