/*
* Copyright 2010 FatWire Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fatwire.gst.foundation.taglib;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import COM.FutureTense.Interfaces.ICS;
import com.fatwire.assetapi.data.AssetId;
import com.fatwire.gst.foundation.facade.mda.DimensionUtils;
import com.fatwire.gst.foundation.facade.mda.LocaleUtils;
import com.fatwire.mda.Dimension;
import com.fatwire.mda.DimensionException;
import com.fatwire.mda.DimensionFilterInstance;
import com.fatwire.mda.DimensionManager;
import com.fatwire.mda.DimensionSetInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* simple tag for translating an asset
*
* @author Tony Field
* @since 2011-11-28
*
*
* @deprecated as of release 12.x
*
*/
public abstract class MultilingualGsfSimpleTag extends GsfSimpleTag {
protected static final Logger LOG = LoggerFactory.getLogger("tools.gsf.legacy.taglib.MultilingualGsfSimpleTag");
private String dimensionSetName = null;
private long dimensionSetId = -1L;
private String localeName = null;
private long localeId = -1L;
public final void setDimset(String s) {
try {
dimensionSetId = Long.parseLong(s);
} catch (NumberFormatException e) {
dimensionSetName = s;
dimensionSetId = -1L;
}
}
public final void setLocale(String s) {
try {
localeId = Long.parseLong(s);
} catch (NumberFormatException e) {
localeName = s;
localeId = -1L;
}
}
/**
* Return a dimension filter instance corresponding to the dimension set specified by the user (or discovered by
* the tag). The dimension filter is configured with the preferred dimensions of the user (also onfigured).
*
* The preferred locales are identified by checking the following locations, in the order specified:
* 1) set by the locale attribute by id of locale
* 2) set by locale attribute by name of locale
* 3) detected by finding the locale dimension id in the ics variable "locale"
* 4) detected by finding the locale name in the ics variable "locale"
* 5) detected by finding the locale dimension id in the ics session variable "locale"
* 6) detected by finding the locale name in the ics session variable "locale"
* 7) detected by reading the Accept-Language header
*
* The dimension set is identified by checking in the following places, in order:
* 1) set by the dimset attribute by name of dimension set
* 2) set by dimset attribute by the id of the dimension set
* 3) looked up by finding the site name in the ics variable "site" and loading the single dimension set associated with that site
*
* @return a dimension filter, configured with the set preferred locales, or null, if either the dimenion set or the
* preferred dimensions could not be found (with extensive errors)
*/
protected final DimensionFilterInstance getDimensionFilter() {
ICS ics = getICS();
DimensionFilterInstance filter;
try {
Collection<AssetId> preferredLocales = getPreferredLocales();
DimensionSetInstance dimSet = getDimensionSet();
filter = DimensionUtils.getDimensionFilter(DimensionUtils.getDM(ics), preferredLocales, dimSet);
if (LOG.isDebugEnabled()) {
LOG.debug("Multilingual-enabled tag located dimension filter: " + filter + " in dimensionSet " + dimSet + " with preferred locales: " + preferredLocales + " ");
}
} catch (DimensionException e) {
LOG.error("Multilingual-enabled tag could not locate dimension filter", e);
filter = null;
} catch (RuntimeException e) {
LOG.error("Multilingual-enabled tag could not locate dimension filter", e);
filter = null;
}
return filter;
}
/**
* Get the locale that the user explicitly specified. If not set, null is returned.
* @return the id of the locale that the user explicitly set. Handles setting by name or assetid.
*/
protected final AssetId getExplicitlySpecifiedLocale() {
ICS ics = getICS();
// first, check for explicitly specified by ID
if (localeId != -1L) {
DimensionManager dm = DimensionUtils.getDM(ics);
Dimension d = dm.loadDimension(localeId);
if (d != null) {
LOG.trace("Preferred locale explicitly set to " + localeId);
return d.getId();
}
}
// next, check for explicitly specified by name
if (localeName != null) {
Dimension d = DimensionUtils.getDimensionForName(ics, localeName);
if (d != null) {
LOG.trace("Preferred locale explicitly set to " + localeName);
return d.getId();
}
}
return null;
}
/**
* Get the ordered list of preferred locales that the user wants. Multiple attempts are made to figure out the right locale.
* @return collection of asset identifiers of the preferred locales
*/
protected final Collection<AssetId> getPreferredLocales() {
AssetId result = getExplicitlySpecifiedLocale();
if (result != null) return Collections.singleton(result);
ICS ics = getICS();
// next, check for implicitly specified by ID using locale variable
String localeVar = getICS().GetVar("locale");
try {
long localeIdFromVar = Long.parseLong(localeVar);
DimensionManager dm = DimensionUtils.getDM(ics);
Dimension d = dm.loadDimension(localeIdFromVar);
if (d != null) {
LOG.trace("Preferred locale detected in ICS context using 'locale' variable: " + localeIdFromVar);
return Collections.singletonList(d.getId());
}
} catch (NumberFormatException e) {
// maybe it's a locale name...
try {
Dimension d = DimensionUtils.getDimensionForName(ics, localeVar);
if (d != null) {
LOG.trace("Preferred locale detected in ICS context using 'locale' variable: " + localeVar);
return Collections.singletonList(d.getId());
}
} catch (Exception ex) {
// nope... don't worry, we'll find it....
}
}
// next, check for implicitly specified by ID using locale session variable
String localeSSVar = getICS().GetSSVar("locale");
try {
long localeIdFromSSVar = Long.parseLong(localeSSVar);
DimensionManager dm = DimensionUtils.getDM(ics);
Dimension d = dm.loadDimension(localeIdFromSSVar);
if (d != null) {
LOG.trace("Preferred locale detected in ICS context using 'locale' session variable: " + localeIdFromSSVar);
return Collections.singletonList(d.getId());
}
} catch (NumberFormatException e) {
// maybe it's a locale name...
try {
Dimension d = DimensionUtils.getDimensionForName(ics, localeSSVar);
if (d != null) {
LOG.trace("Preferred locale detected in ICS context using 'locale' session variable: " + localeSSVar);
return Collections.singletonList(d.getId());
}
} catch (Exception ex) {
// nope... don't worry, we'll find it....
}
}
// finally, get the locale from the servlet request's Accept-Language header..
List<AssetId> preferredLocales = new ArrayList<AssetId>();
@SuppressWarnings({ "rawtypes", "deprecation" })
Enumeration locales = ics.getIServlet().getServletRequest().getLocales();
while (locales.hasMoreElements()) {
Locale locale = (Locale) locales.nextElement();
if (locale != null) {
String localeName = locale.toString();
if (localeName != null && localeName.length() > 0) {
try {
Dimension dimension = DimensionUtils.getDimensionForName(ics, localeName);
preferredLocales.add(dimension.getId());
LOG.trace("Found registered locale in user's Accept-Language header (or default): " + localeName);
} catch (RuntimeException e) {
// don't care if the dimension is not in the system - they probably won't all be there
// and we're guessing anyway, so it's okay.
LOG.trace("Found a locale in the user's Accept-Language header, but it was not registered as a dimension: " + localeName + " (this is not usually an error)", e);
}
}
}
}
return preferredLocales;
}
private final DimensionSetInstance getDimensionSet() {
if (dimensionSetName != null) {
return LocaleUtils.getDimensionSet(getICS(), dimensionSetName);
}
if (dimensionSetId != -1L) {
return LocaleUtils.getDimensionSet(getICS(), dimensionSetId);
}
try {
ICS ics = getICS();
String site = ics.GetVar("site");
if (site != null && site.length() > 0) {
long discoveredId = LocaleUtils.locateDimensionSetForSite(ics, site);
LOG.trace("Auto-discovered dimension set because there is only one in site " + site + ": DimensionSet:" + discoveredId);
return LocaleUtils.getDimensionSet(ics, discoveredId);
}
} catch (RuntimeException e) {
LOG.trace("Could not auto-discovered dimensionset: " + e);
}
throw new IllegalArgumentException("DimensionSet not found");
}
}