/*
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;
import java.rmi.RemoteException;
import java.util.Stack;
import com.servoy.j2db.dataprocessing.DataServerProxy;
import com.servoy.j2db.dataprocessing.FoundSetManager;
import com.servoy.j2db.dataprocessing.IDataServer;
import com.servoy.j2db.dataprocessing.IDataSet;
import com.servoy.j2db.dataprocessing.IUserClient;
import com.servoy.j2db.scripting.StartupArguments;
import com.servoy.j2db.util.DataSourceUtils;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.IGetStatusLine;
/**
* Remote class for server calls to client
*
* @author jblok
*/
public class ClientStub implements IUserClient
{
private transient final ClientState client;
public ClientStub(ClientState c)
{
client = c;
}
public void alert(final String msg)
{
client.getScheduledExecutor().execute(new Runnable()
{
public void run()
{
client.invokeLater(new Runnable()
{
public void run()
{
client.reportInfo(msg); //Messages.getString("servoy.userClient.message.fromServer")
}
});
}
});
}
public boolean isAlive()
{
return true;//just rerurn call
}
public void shutDown()
{
client.getScheduledExecutor().execute(new Runnable()
{
public void run()
{
client.invokeLater(new Runnable()
{
public void run()
{
synchronized (ClientStub.this)
{
client.shutDown(true);
}
}
}, true);
}
});
}
public void closeSolution()
{
client.getScheduledExecutor().execute(new Runnable()
{
public void run()
{
client.invokeLater(new Runnable()
{
public void run()
{
synchronized (ClientStub.this)
{
client.closeSolution(true, null);
client.reportInfo(client.getI18NMessage("servoy.client.message.remotesolutionclose")); //$NON-NLS-1$
}
}
}, true);
}
});
}
public void flushCachedDatabaseData(final String dataSource)
{
if (client.isShutDown()) return;
client.getScheduledExecutor().execute(new Runnable()
{
public void run()
{
Runnable r = new Runnable()
{
public void run()
{
IDataServer dataServer = client.getDataServer();
if (dataServer instanceof DataServerProxy)
{
String[] dbServernameTablename = DataSourceUtils.getDBServernameTablename(dataSource);
if (dbServernameTablename != null)
{
// map from real db server to server names from before switch-server
for (String srv : ((DataServerProxy)dataServer).getReverseMappedServerNames(dbServernameTablename[0]))
{
((FoundSetManager)client.getFoundSetManager()).flushCachedDatabaseDataFromRemote(DataSourceUtils.createDBTableDataSource(
srv, dbServernameTablename[1]));
}
return;
}
}
((FoundSetManager)client.getFoundSetManager()).flushCachedDatabaseDataFromRemote(dataSource);
}
};
if (client.isEventDispatchThread())
{
r.run();
}
else
{
client.invokeLater(r);
}
}
});
}
private final Stack<Object[]> datachanges = new Stack<Object[]>();
private Runnable datachangesHandler;
public void notifyDataChange(final String server_name, final String table_name, final IDataSet pks, final int sql_action, final Object[] insertColumnData)
{
if (client.isShutDown()) return;
if (Debug.tracing())
{
Debug.trace("Notify Data Change get from the server for dataserver: " + server_name + " table: " + table_name); //$NON-NLS-1$ //$NON-NLS-2$
}
synchronized (datachanges)
{
datachanges.push(new Object[] { server_name, table_name, pks, new Integer(sql_action), insertColumnData });
if (datachangesHandler == null)
{
datachangesHandler = new Runnable()
{
public void run()
{
while (datachangesHandler != null)
{
final Object[] array;
synchronized (datachanges)
{
if (datachanges.isEmpty())
{
datachangesHandler = null; // done
break;
}
array = datachanges.pop();
}
client.invokeLater(new Runnable()
{
public void run()
{
if (client.isShutDown()) return;
String sname = (String)array[0];
String tname = (String)array[1];
IDataSet pksDataSet = (IDataSet)array[2];
int action = ((Integer)array[3]).intValue();
Object[] insertColumndata = (Object[])array[4];
IDataServer ds = client.getDataServer();
if (ds instanceof DataServerProxy)
{
// possibly switched from multiple servers to the same destination server.
for (String srv : ((DataServerProxy)ds).getReverseMappedServerNames(sname))
{
((FoundSetManager)client.getFoundSetManager()).notifyDataChange(
DataSourceUtils.createDBTableDataSource(srv, tname), pksDataSet, action, insertColumndata);
}
return;
}
// not switched
((FoundSetManager)client.getFoundSetManager()).notifyDataChange(DataSourceUtils.createDBTableDataSource(sname, tname),
pksDataSet, action, insertColumndata);
}
});
}
}
};
client.getScheduledExecutor().execute(datachangesHandler);
}
}
}
public void activateSolutionMethod(final String globalMethodName, final StartupArguments argumentsScope)
{
client.getScheduledExecutor().execute(new Runnable()
{
public void run()
{
client.invokeLater(new Runnable()
{
public void run()
{
client.activateSolutionMethod(globalMethodName, argumentsScope);
}
});
}
});
}
@Override
public String getClientStatusLine() throws RemoteException
{
if (client instanceof IGetStatusLine)
{
return ((IGetStatusLine)client).getStatusLine();
}
return null;
}
}