/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.
This program 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program; if not, see http://www.gnu.org/licenses or write to the Free
Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
package com.servoy.j2db.persistence;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import com.servoy.base.query.IBaseSQLCondition;
import com.servoy.j2db.dataprocessing.FoundSetManager;
import com.servoy.j2db.dataprocessing.IDataServer;
import com.servoy.j2db.dataprocessing.IDataSet;
import com.servoy.j2db.dataprocessing.IFoundSetManagerInternal;
import com.servoy.j2db.dataprocessing.ISQLActionTypes;
import com.servoy.j2db.dataprocessing.ISQLStatement;
import com.servoy.j2db.dataprocessing.SQLStatement;
import com.servoy.j2db.query.CompareCondition;
import com.servoy.j2db.query.QueryColumn;
import com.servoy.j2db.query.QueryColumnValue;
import com.servoy.j2db.query.QueryDelete;
import com.servoy.j2db.query.QueryInsert;
import com.servoy.j2db.query.QuerySelect;
import com.servoy.j2db.query.QuerySort;
import com.servoy.j2db.query.QueryTable;
import com.servoy.j2db.query.QueryUpdate;
import com.servoy.j2db.util.Utils;
/**
* Utility class for loading/saving i18n texts in the repository
*
* @author gboros
*/
public class I18NUtil
{
static public class MessageEntry
{
String language;
String key;
String value;
public MessageEntry(String language, String key, String value)
{
this.language = language == null ? "" : language;
this.key = key == null ? "" : key;
this.value = value == null ? "" : value;
}
public String getLanguageKey()
{
return language + '.' + key;
}
public String getLanguage()
{
return language;
}
public String getKey()
{
return key;
}
public String getValue()
{
return value;
}
@Override
public String toString()
{
return getValue();
}
}
public static void writeMessagesToRepository(String i18NServerName, String i18NTableName, IRepository repository, IDataServer dataServer, String clientID,
TreeMap<String, MessageEntry> messages, boolean noUpdates, boolean noRemoves, String filterName, String[] filterValue, FoundSetManager fm)
throws Exception
{
writeMessagesToRepository(i18NServerName, i18NTableName, repository, dataServer, clientID, messages, noUpdates, noRemoves, null, filterName,
filterValue, fm);
}
public static void writeMessagesToRepository(String i18NServerName, String i18NTableName, IRepository repository, IDataServer dataServer, String clientID,
TreeMap<String, MessageEntry> messages, boolean noUpdates, boolean noRemoves, TreeMap<String, MessageEntry> remoteMessages, String filterName,
String[] filterValue, IFoundSetManagerInternal fm) throws Exception
{
// get remote messages snapshot
if (remoteMessages == null) remoteMessages = loadSortedMessagesFromRepository(repository, dataServer, clientID, i18NServerName, i18NTableName,
filterName, filterValue, fm);
if (remoteMessages != null)
{
IServer i18NServer = repository.getServer(i18NServerName);
Table i18NTable = null;
if (i18NServer != null)
{
i18NTable = (Table)i18NServer.getTable(i18NTableName);
}
if (i18NTable != null)
{
Column pkColumn = i18NTable.getRowIdentColumns().get(0); // runtime exception when no ident columns
QueryTable messagesTable = new QueryTable(i18NTable.getSQLName(), i18NTable.getDataSource(), i18NTable.getCatalog(), i18NTable.getSchema());
QueryColumn pkCol = new QueryColumn(messagesTable, pkColumn.getID(), pkColumn.getSQLName(), pkColumn.getType(), pkColumn.getLength(),
pkColumn.getScale(), pkColumn.getFlags());
QueryColumn msgLang = new QueryColumn(messagesTable, -1, "message_language", Types.VARCHAR, 5, 0, 0);
QueryColumn msgKey = new QueryColumn(messagesTable, -1, "message_key", Types.VARCHAR, 150, 0, 0);
QueryColumn msgVal = new QueryColumn(messagesTable, -1, "message_value", Types.VARCHAR, 2000, 0, 0);
ArrayList<SQLStatement> updateStatements = new ArrayList<SQLStatement>();
// go thorough messages, update exiting, add news to remote
// in case we need to insert a record, we must know if it is database managed or servoy managed
boolean logIdIsServoyManaged = false;
ColumnInfo ci = pkColumn.getColumnInfo();
if (ci != null)
{
int autoEnterType = ci.getAutoEnterType();
int autoEnterSubType = ci.getAutoEnterSubType();
logIdIsServoyManaged = (autoEnterType == ColumnInfo.SEQUENCE_AUTO_ENTER) && (autoEnterSubType != ColumnInfo.NO_SEQUENCE_SELECTED) &&
(autoEnterSubType != ColumnInfo.DATABASE_IDENTITY);
}
Iterator<Map.Entry<String, MessageEntry>> messagesIte = messages.entrySet().iterator();
Map.Entry<String, MessageEntry> messageEntry;
while (messagesIte.hasNext())
{
messageEntry = messagesIte.next();
String key = messageEntry.getKey();
String value = messageEntry.getValue().getValue();
String lang = messageEntry.getValue().getLanguage();
if (lang.equals("")) lang = null;
String messageKey = messageEntry.getValue().getKey();
if (!remoteMessages.containsKey(key)) // insert
{
QueryInsert insert = new QueryInsert(messagesTable);
QueryColumn[] insertColumns = null;
Object[] insertColumnValues = null;
if (logIdIsServoyManaged)
{
Object messageId = dataServer.getNextSequence(i18NServerName, i18NTableName, pkColumn.getName(), -1);
if (lang == null)
{
insertColumns = new QueryColumn[] { pkCol, msgKey, msgVal };
insertColumnValues = new Object[] { messageId, messageKey, value };
}
else
{
insertColumns = new QueryColumn[] { pkCol, msgKey, msgLang, msgVal };
insertColumnValues = new Object[] { messageId, messageKey, lang, value };
}
}
else
{
if (lang == null)
{
insertColumns = new QueryColumn[] { msgKey, msgVal };
insertColumnValues = new Object[] { messageKey, value };
}
else
{
insertColumns = new QueryColumn[] { msgKey, msgLang, msgVal };
insertColumnValues = new Object[] { messageKey, lang, value };
}
}
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0)
{
insertColumns = Utils.arrayAdd(insertColumns, new QueryColumn(messagesTable, filterColumn.getID(), filterColumn.getSQLName(),
filterColumn.getType(), filterColumn.getLength(), filterColumn.getScale(), filterColumn.getFlags()), true);
insertColumnValues = Utils.arrayAdd(insertColumnValues, filterValue[0], true);
}
insert.setColumnValues(insertColumns, insertColumnValues);
updateStatements.add(new SQLStatement(ISQLActionTypes.INSERT_ACTION, i18NServerName, i18NTableName, null, null, insert, null));
}
else if (!remoteMessages.get(key).getValue().equals(value) && !noUpdates) // update
{
QueryUpdate update = new QueryUpdate(messagesTable);
update.addValue(msgVal, value);
update.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgKey, messageKey));
update.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgLang, lang));
if (filterName != null)
{
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0)
{
QueryColumn columnFilter = new QueryColumn(messagesTable, filterColumn.getID(), filterColumn.getSQLName(),
filterColumn.getType(), filterColumn.getLength(), filterColumn.getScale(), filterColumn.getFlags());
CompareCondition cc = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, columnFilter, new QueryColumnValue(
filterValue[0], null));
update.addCondition("FILTER", cc);
}
}
updateStatements.add(new SQLStatement(ISQLActionTypes.UPDATE_ACTION, i18NServerName, i18NTableName, null, null, update, fm != null
? fm.getTableFilterParams(i18NServerName, update) : null));
}
}
if (!noRemoves)
{
// go thorough remote, remove if not existing locally
Iterator<Map.Entry<String, MessageEntry>> remoteMessagesIte = remoteMessages.entrySet().iterator();
Map.Entry<String, MessageEntry> remoteMessageEntry;
while (remoteMessagesIte.hasNext())
{
remoteMessageEntry = remoteMessagesIte.next();
String key = remoteMessageEntry.getKey();
if (!messages.containsKey(key)) // delete
{
String lang = remoteMessageEntry.getValue().getLanguage();
if (lang.equals("")) lang = null;
String messageKey = remoteMessageEntry.getValue().getKey();
QueryDelete delete = new QueryDelete(messagesTable);
delete.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgKey, messageKey));
delete.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgLang, lang));
if (filterName != null)
{
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0)
{
QueryColumn columnFilter = new QueryColumn(messagesTable, filterColumn.getID(), filterColumn.getSQLName(),
filterColumn.getType(), filterColumn.getLength(), filterColumn.getScale(), filterColumn.getFlags());
CompareCondition cc = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, columnFilter, new QueryColumnValue(
filterValue[0], null));
delete.addCondition(cc);
}
}
updateStatements.add(new SQLStatement(ISQLActionTypes.DELETE_ACTION, i18NServerName, i18NTableName, null, null, delete, fm != null
? fm.getTableFilterParams(i18NServerName, delete) : null));
}
}
}
for (SQLStatement st : updateStatements)
{
st.setDataType(ISQLStatement.I18N_DATA_TYPE);
}
dataServer.performUpdates(clientID, updateStatements.toArray(new ISQLStatement[updateStatements.size()]));
}
}
}
public static TreeMap<String, MessageEntry> loadSortedMessagesFromRepository(IRepository repository, IDataServer dataServer, String clientID,
String i18NServerName, String i18NTableName, String filterName, String[] filterValue, IFoundSetManagerInternal fm) throws Exception
{
TreeMap<String, MessageEntry> sortedMessages = new TreeMap<String, MessageEntry>();
IServer i18NServer = repository.getServer(i18NServerName);
if (i18NServer != null)
{
Table i18NTable = (Table)i18NServer.getTable(i18NTableName);
if (i18NTable != null)
{
QueryTable messagesTable = new QueryTable(i18NTable.getSQLName(), i18NTable.getDataSource(), i18NTable.getCatalog(), i18NTable.getSchema());
QuerySelect sql = new QuerySelect(messagesTable);
QueryColumn msgLang = new QueryColumn(messagesTable, -1, "message_language", Types.VARCHAR, 5, 0, 0);
QueryColumn msgKey = new QueryColumn(messagesTable, -1, "message_key", Types.VARCHAR, 150, 0, 0);
QueryColumn msgVal = new QueryColumn(messagesTable, -1, "message_value", Types.VARCHAR, 2000, 0, 0);
sql.addColumn(msgLang);
sql.addColumn(msgKey);
sql.addColumn(msgVal);
if (filterName != null)
{
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0)
{
QueryColumn columnFilter = new QueryColumn(messagesTable, filterColumn.getID(), filterColumn.getSQLName(), filterColumn.getType(),
filterColumn.getLength(), filterColumn.getScale(), filterColumn.getFlags());
CompareCondition cc = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, columnFilter, new QueryColumnValue(filterValue[0], null));
sql.addCondition("FILTER", cc); //$NON-NLS-1$
}
}
sql.addSort(new QuerySort(msgLang, true));
sql.addSort(new QuerySort(msgKey, true));
IDataSet set = dataServer.performQuery(clientID, i18NServerName, null, sql, fm != null ? fm.getTableFilterParams(i18NServerName, sql) : null,
false, 0, Integer.MAX_VALUE, IDataServer.MESSAGES_QUERY);
int rowCount = set.getRowCount();
if (rowCount > 0)
{
for (int i = 0; i < rowCount; i++)
{
Object[] row = set.getRow(i);
MessageEntry messageEntry = new MessageEntry((String)row[0], (String)row[1], (String)row[2]);
sortedMessages.put(messageEntry.getLanguageKey(), messageEntry);
}
}
}
}
return sortedMessages;
}
}