/* * Copyright (C) 2013-2017 NTT DATA Corporation * * 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 org.terasoluna.gfw.common.codelist.i18n; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; import org.terasoluna.gfw.common.codelist.CodeList; import com.google.common.base.Supplier; import com.google.common.collect.Maps; import com.google.common.collect.Table; import com.google.common.collect.Tables; /** * Simple implementation of {@link I18nCodeList}<br> * <p> * {@link I18nCodeList} has a table of codelist.<br> * Each row is a codelist for each language and represented as <strong>unmodifiable linked hash maps</strong>.<br> * The key of rows is {@link Locale}.The key of columns is {@link String}(code). <br> * There are 3 ways to express the following table. * </p> * <table border=1> * <caption>code list table of week</caption> * <tr> * <th>row=Locale,column=code</th> * <th>0</th> * <th>1</th> * <th>2</th> * <th>3</th> * <th>4</th> * <th>5</th> * <th>6</th> * </tr> * <tr> * <th>en</th> * <td>Sun.</td> * <td>Mon.</td> * <td>Tue.</td> * <td>Wed.</td> * <td>Thu.</td> * <td>Fri.</td> * <td>Sat.</td> * </tr> * <tr> * <th>ja</th> * <td>日</td> * <td>月</td> * <td>火</td> * <td>水</td> * <td>木</td> * <td>金</td> * <td>土</td> * </tr> * </table> * <h3>(Way 1) set by rows</h3> * * <pre> * <bean id="CL_I18N_WEEK" * class="org.terasoluna.gfw.common.codelist.i18n.SimpleI18nCodeList"> * <property name="rows"> * <util:map> * <entry key="en"> * <util:map> * <entry key="0" value="Sun." /> * <entry key="1" value="Mon." /> * <entry key="2" value="Tue." /> * <entry key="3" value="Wed." /> * <entry key="4" value="Thu." /> * <entry key="5" value="Fri." /> * <entry key="6" value="Sat." /> * </util:map> * </entry> * <entry key="ja"> * <util:map> * <entry key="0" value="日" /> * <entry key="1" value="月" /> * <entry key="2" value="火" /> * <entry key="3" value="水" /> * <entry key="4" value="木" /> * <entry key="5" value="金" /> * <entry key="6" value="土" /> * </util:map> * </entry> * </util:map> * </property> * </bean> * </pre> * * <h3>(Way2) set by rows with codelist</h3> * * <pre> * <bean id="CL_I18N_WEEK" * class="org.terasoluna.gfw.common.codelist.i18n.SimpleI18nCodeList"> * <property name="rowsByCodeList"> * <util:map> * <entry key="en" value-ref="CL_WEEK_EN" /> * <entry key="ja" value-ref="CL_WEEK_JA" /> * </util:map> * </property> * </bean> * * <bean id="CL_WEEK_EN" class="org.terasoluna.gfw.common.codelist.SimpleMapCodeList"> * <property name="map"> * <util:map> * <entry key="0" value="Sun." /> * <entry key="1" value="Mon." /> * <entry key="2" value="Tue." /> * <entry key="3" value="Wed." /> * <entry key="4" value="Thu." /> * <entry key="5" value="Fri." /> * <entry key="6" value="Sat." /> * </util:map> * </property> * </bean> * * <bean id="CL_WEEK_JA" class="org.terasoluna.gfw.common.codelist.SimpleMapCodeList"> * <property name="map"> * <util:map> * <entry key="0" value="日" /> * <entry key="1" value="月" /> * <entry key="2" value="火" /> * <entry key="3" value="水" /> * <entry key="4" value="木" /> * <entry key="5" value="金" /> * <entry key="6" value="土" /> * </util:map> * </property> * </bean> * </pre> * * <h3>(Way3) set by columns</h3> * * <pre> * <bean id="CL_I18N_WEEK" * class="org.terasoluna.gfw.common.codelist.i18n.SimpleI18nCodeList"> * <property name="columns"> * <util:map> * <entry key="0"> * <util:map> * <entry key="en" value="Sun." /> * <entry key="ja" value="日" /> * </util:map> * </entry> * <entry key="1"> * <util:map> * <entry key="en" value="Mon." /> * <entry key="ja" value="月" /> * </util:map> * </entry> * <entry key="2"> * <util:map> * <entry key="en" value="Tue." /> * <entry key="ja" value="火" /> * </util:map> * </entry> * <entry key="3"> * <util:map> * <entry key="en" value="Wed." /> * <entry key="ja" value="水" /> * </util:map> * </entry> * <entry key="4"> * <util:map> * <entry key="en" value="Thu." /> * <entry key="ja" value="木" /> * </util:map> * </entry> * <entry key="5"> * <util:map> * <entry key="en" value="Fri." /> * <entry key="ja" value="金" /> * </util:map> * </entry> * <entry key="6"> * <util:map> * <entry key="en" value="Sat." /> * <entry key="ja" value="土" /> * </util:map> * </entry> * </util:map> * </property> * </bean> * </pre> */ public class SimpleI18nCodeList extends AbstractI18nCodeList implements InitializingBean { /** * Logger. */ private static final Logger logger = LoggerFactory .getLogger(SimpleI18nCodeList.class); /** * codelist table. */ Table<Locale, String, String> codeListTable; /** * supplier to return a {@link LinkedHashMap} object. */ private static final Supplier<LinkedHashMap<String, String>> LINKED_HASH_MAP_SUPPLIER = new Supplier<LinkedHashMap<String, String>>() { @Override public LinkedHashMap<String, String> get() { return Maps.newLinkedHashMap(); } }; /** * <p> * returns row of codelist table. * </p> * @see org.terasoluna.gfw.common.codelist.i18n.I18nCodeList#asMap(java.util.Locale) */ @Override public Map<String, String> asMap(Locale locale) { Assert.notNull(locale, "locale is null"); return codeListTable.row(locale); } /** * check whether the code list table is null.<br> * <p> * output warn log in case of table is null. * </p> */ private void checkTable() { if (codeListTable != null) { logger.warn("Codelist table has already built, but re-build"); } } /** * set table by rows ({@link Map}).<br> * <p> * The key is {@link Locale} and the value is {@link Map} which represents {@link CodeList}.<br> * </p> * @param rows table by rows ({@link Map}) per locale */ public void setRows(Map<Locale, Map<String, String>> rows) { checkTable(); Table<Locale, String, String> table = createTable(); for (Map.Entry<Locale, Map<String, String>> e : rows.entrySet()) { Locale locale = e.getKey(); Map<String, String> row = e.getValue(); for (Map.Entry<String, String> re : row.entrySet()) { String value = re.getKey(); String label = re.getValue(); table.put(locale, value, label); } } this.codeListTable = Tables.unmodifiableTable(table); } /** * set table by rows ({@link CodeList})<br> * <p> * The key is {@link Locale} and the value is {@link CodeList}.<br> * </p> * @param rows table by rows ({@link CodeList}) per locale */ public void setRowsByCodeList(Map<Locale, CodeList> rows) { checkTable(); Table<Locale, String, String> table = createTable(); for (Map.Entry<Locale, CodeList> e : rows.entrySet()) { Locale locale = e.getKey(); Map<String, String> row = e.getValue().asMap(); for (Map.Entry<String, String> re : row.entrySet()) { String value = re.getKey(); String label = re.getValue(); table.put(locale, value, label); } } this.codeListTable = Tables.unmodifiableTable(table); } /** * set table by columns ({@link Map})<br> * <p> * The key is {@link Locale} and value is {@link Map}. <br> * </p> * @param cols table by columns ({@link Map}) per locale */ public void setColumns(Map<String, Map<Locale, String>> cols) { checkTable(); Table<Locale, String, String> table = createTable(); for (Map.Entry<String, Map<Locale, String>> e : cols.entrySet()) { String value = e.getKey(); Map<Locale, String> col = e.getValue(); for (Map.Entry<Locale, String> ce : col.entrySet()) { Locale locale = ce.getKey(); String label = ce.getValue(); table.put(locale, value, label); } } this.codeListTable = Tables.unmodifiableTable(table); } /** * create table which consist of {@link LinkedHashMap} factory. * @return table */ private Table<Locale, String, String> createTable() { Map<Locale, Map<String, String>> backingMap = Maps.newLinkedHashMap(); Table<Locale, String, String> table = Tables.newCustomTable(backingMap, LINKED_HASH_MAP_SUPPLIER); return table; } /** * <p> * check whether codeListTable is initialized. * </p> * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ @Override public void afterPropertiesSet() { Assert.notNull(codeListTable, "codeListTable is not initialized!"); } }