/**
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.portal.mop.i18n;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.chromattic.api.annotations.Create;
import org.chromattic.api.annotations.MappedBy;
import org.chromattic.api.annotations.MixinType;
import org.chromattic.api.annotations.OneToOne;
import org.chromattic.api.annotations.Owner;
import org.exoplatform.commons.utils.I18N;
import org.gatein.common.logging.Logger;
import org.gatein.common.logging.LoggerFactory;
/**
* @author <a href="mailto:khoi.nguyen@exoplatform.com">Nguyen Duc Khoi</a>
* Apr 15, 2011
*/
/**
* The entry point for carrying the information and can be attached to mop entities
*/
@MixinType(name = "gtn:i18nized")
public abstract class I18Nized {
/** . */
private static final Logger log = LoggerFactory.getLogger(I18Nized.class);
private static Locale parent(Locale locale) {
if (locale.getVariant() != null && !locale.getVariant().isEmpty()) {
return new Locale(locale.getLanguage(), locale.getCountry());
} else if (locale.getCountry() != null && !locale.getCountry().isEmpty()) {
return new Locale(locale.getLanguage());
} else {
return null;
}
}
@Create
protected abstract LanguageSpace createLanguageSpace();
@OneToOne
@Owner
@MappedBy("gtn:languages")
protected abstract LanguageSpace getLanguageSpace();
protected abstract void setLanguageSpace(LanguageSpace languageSpace);
public <M> Resolution<M> resolveMixin(Class<M> mixinType, Locale wantedLocale) {
if (mixinType == null) {
throw new NullPointerException("No null mixin type accepted");
}
if (wantedLocale == null) {
throw new NullPointerException("No null wanted locale accepted");
}
for (Locale current = wantedLocale; current != null; current = parent(current)) {
M mixin = getMixin(mixinType, current, false);
if (mixin != null) {
return new Resolution<M>(current, mixin);
}
}
return null;
}
public <M> Map<Locale, M> getMixins(Class<M> mixinType) {
if (mixinType == null) {
throw new NullPointerException("No null mixin type accepted");
}
Map<Locale, M> mixins = new HashMap<Locale, M>();
LanguageSpace languageSpace = getLanguageSpace();
if (languageSpace != null) {
for (Map.Entry<String, Language> entry : languageSpace.getChildren().entrySet()) {
M mixin = entry.getValue().getMixin(mixinType, false);
if (mixin != null) {
String lang = entry.getKey();
try {
Locale locale = I18N.parseTagIdentifier(lang);
mixins.put(locale, mixin);
} catch (IllegalArgumentException e) {
log.debug("Skipping locale " + lang + " from retrieved locales for mixin " + mixinType.getName());
}
}
}
}
return mixins;
}
public <M> M getMixin(Class<M> mixinType, Locale locale, boolean createMixin) throws NullPointerException,
IllegalArgumentException {
if (mixinType == null) {
throw new NullPointerException("No null mixin type accepted");
}
if (locale == null) {
throw new NullPointerException("No null locale accepted");
}
if (locale.getLanguage().length() == 0) {
throw new IllegalArgumentException("No language set on locale");
}
if (locale.getVariant().length() > 0) {
throw new IllegalArgumentException("No variant cab be set on locale");
}
LanguageSpace languageSpace = getLanguageSpace();
if (languageSpace == null && createMixin) {
languageSpace = createLanguageSpace();
setLanguageSpace(languageSpace);
}
if (languageSpace != null) {
return languageSpace.getLanguage(mixinType, I18N.toTagIdentifier(locale), createMixin);
} else {
return null;
}
}
public <M> Collection<Locale> removeMixin(Class<M> mixinType) {
if (mixinType == null) {
throw new NullPointerException("No null mixin type accepted");
}
Collection<Locale> locales = Collections.emptyList();
LanguageSpace languageSpace = getLanguageSpace();
if (languageSpace != null) {
for (Language language : languageSpace.getChildren().values()) {
if (language.removeMixin(mixinType)) {
String lang = language.getName();
try {
Locale locale = I18N.parseTagIdentifier(lang);
if (locales.isEmpty()) {
locales = new ArrayList<Locale>();
}
locales.add(locale);
} catch (IllegalArgumentException e) {
log.debug("Skipping locale " + lang + " from removed locales for mixin " + mixinType.getName());
}
}
}
}
return locales;
}
}