/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2015 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.server.ngclient;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.WeakHashMap;
import org.json.JSONObject;
import org.sablo.specification.PropertyDescription;
import org.sablo.specification.property.ChangeAwareList;
import org.sablo.specification.property.ChangeAwareMap;
import org.sablo.websocket.IServerService;
import org.sablo.websocket.TypedData;
import com.servoy.j2db.IApplication;
import com.servoy.j2db.dataprocessing.FoundSetManager;
import com.servoy.j2db.dataprocessing.IFoundSetFactory;
import com.servoy.j2db.dataprocessing.IFoundSetInternal;
import com.servoy.j2db.dataprocessing.IRecordInternal;
import com.servoy.j2db.server.ngclient.property.FoundsetPropertyTypeConfig;
import com.servoy.j2db.server.ngclient.property.FoundsetTypeSabloValue;
import com.servoy.j2db.server.ngclient.property.types.FoundsetReferencePropertyType;
import com.servoy.j2db.util.Pair;
/**
* @author gboros
*
*/
public class NGFoundSetManager extends FoundSetManager implements IServerService
{
public static final String FOUNDSET_SERVICE = "$foundsetManager"; //$NON-NLS-1$
/**
* @param application
*/
public NGFoundSetManager(IApplication app, IFoundSetFactory factory)
{
super(app, factory);
((NGClient)getApplication()).getWebsocketSession().registerServerService(FOUNDSET_SERVICE, this);
}
@SuppressWarnings("nls")
@Override
public Object executeMethod(String methodName, JSONObject args) throws Exception
{
if ("getFoundSet".equals(methodName))
{
IFoundSetInternal foundset = FoundsetReferencePropertyType.INSTANCE.fromJSON(args, null, null, null, null);
String sort = args.optString("sort");
if (!"".equals(sort))
{
foundset.setSort(sort);
}
FoundsetTypeSabloValue value = getFoundsetTypeSabloValue(foundset, args.optJSONObject("dataproviders"));
ChangeAwareList<ChangeAwareMap<String, Object>, Object> foundsets = (ChangeAwareList<ChangeAwareMap<String, Object>, Object>)((NGClient)getApplication()).getWebsocketSession().getClientService(
"foundset_manager").getProperty("foundsets");
if (foundsets == null)
{
foundsets = new ChangeAwareList<ChangeAwareMap<String, Object>, Object>(new ArrayList<ChangeAwareMap<String, Object>>());
((NGClient)getApplication()).getWebsocketSession().getClientService("foundset_manager").setProperty("foundsets", foundsets);
}
boolean newFoundsetInfo = true;
for (ChangeAwareMap<String, Object> foundsetInfoMap : foundsets)
{
if (foundsetInfoMap.containsValue(value))
{
newFoundsetInfo = false;
break;
}
}
if (newFoundsetInfo)
{
HashMap<String, Object> foundsetinfoMap = new HashMap<String, Object>();
foundsetinfoMap.put("foundset", value);
foundsetinfoMap.put("foundsethash", Integer.valueOf(args.optInt("foundsethash")));
foundsets.add(new ChangeAwareMap(foundsetinfoMap));
}
}
else if ("getRelatedFoundSetHash".equals(methodName))
{
IFoundSetInternal foundset = FoundsetReferencePropertyType.INSTANCE.fromJSON(args, null, null, null, null);
String rowid = args.optString("rowid");
String relation = args.optString("relation");
Pair<String, Integer> splitHashAndIndex = FoundsetTypeSabloValue.splitPKHashAndIndex(rowid);
int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
if (recordIndex != -1)
{
IRecordInternal record = foundset.getRecord(recordIndex);
Object o = record.getValue(relation);
if (o instanceof IFoundSetInternal)
{
IFoundSetInternal relatedFoundset = (IFoundSetInternal)o;
PropertyDescription foundsetRefProperty = new PropertyDescription("", FoundsetReferencePropertyType.INSTANCE);
return new TypedData<IFoundSetInternal>(relatedFoundset, foundsetRefProperty);
}
}
}
else if ("updateFoundSetRow".equals(methodName))
{
IFoundSetInternal foundset = FoundsetReferencePropertyType.INSTANCE.fromJSON(args, null, null, null, null);
String rowid = args.optString("rowid");
String dataproviderid = args.optString("dataproviderid");
Object value = args.get("value");
Pair<String, Integer> splitHashAndIndex = FoundsetTypeSabloValue.splitPKHashAndIndex(rowid);
int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
if (recordIndex != -1)
{
IRecordInternal record = foundset.getRecord(recordIndex);
if (record.startEditing())
{
record.setValue(dataproviderid, value);
return Boolean.TRUE;
}
}
}
else if ("removeFoundSetFromCache".equals(methodName))
{
IFoundSetInternal foundset = FoundsetReferencePropertyType.INSTANCE.fromJSON(args, null, null, null, null);
removeFoundSetTypeSabloValue(foundset);
}
else if ("removeFoundSetsFromCache".equals(methodName))
{
ChangeAwareList<ChangeAwareMap<String, Object>, Object> foundsets = (ChangeAwareList<ChangeAwareMap<String, Object>, Object>)((NGClient)getApplication()).getWebsocketSession().getClientService(
"foundset_manager").getProperty("foundsets");
if (foundsets != null)
{
foundsets.clear();
}
foundsetTypeSabloValueMap.clear();
}
return null;
}
public void removeFoundSetTypeSabloValue(IFoundSetInternal foundset)
{
if (foundset != null)
{
FoundsetTypeSabloValue value = foundsetTypeSabloValueMap.remove(foundset);
ChangeAwareList<ChangeAwareMap<String, Object>, Object> foundsets = (ChangeAwareList<ChangeAwareMap<String, Object>, Object>)((NGClient)getApplication()).getWebsocketSession().getClientService(
"foundset_manager").getProperty("foundsets");
if (foundsets != null)
{
int i = 0;
for (; i < foundsets.size(); i++)
{
ChangeAwareMap<String, Object> foundsetInfoMap = foundsets.get(i);
if (foundsetInfoMap.containsValue(value)) break;
}
if (i < foundsets.size())
{
foundsets.remove(i);
}
}
}
}
@Override
public void flushCachedItems()
{
for (IFoundSetInternal foundset : foundsetTypeSabloValueMap.keySet().toArray(new IFoundSetInternal[foundsetTypeSabloValueMap.size()]))
{
foundsetTypeSabloValueMap.remove(foundset);
}
super.flushCachedItems();
}
private final WeakHashMap<IFoundSetInternal, FoundsetTypeSabloValue> foundsetTypeSabloValueMap = new WeakHashMap<IFoundSetInternal, FoundsetTypeSabloValue>();
private FoundsetTypeSabloValue getFoundsetTypeSabloValue(IFoundSetInternal foundset, JSONObject dataproviders)
{
FoundsetTypeSabloValue foundsetTypeSabloValue = foundsetTypeSabloValueMap.get(foundset);
if (foundsetTypeSabloValue == null)
{
foundsetTypeSabloValue = new FoundsetTypeSabloValue(new JSONObject(), null, null, new FoundsetPropertyTypeConfig(false, false, null))
{
@Override
protected void updateFoundset(IRecordInternal record)
{
if (record != null)
{
super.updateFoundset(record);
}
}
};
foundsetTypeSabloValue.updateFoundset(foundset);
foundsetTypeSabloValueMap.put(foundset, foundsetTypeSabloValue);
}
foundsetTypeSabloValue.initializeDataproviders(dataproviders);
foundsetTypeSabloValue.getViewPort().setBounds(0, foundsetTypeSabloValue.getFoundset().getSize());
return foundsetTypeSabloValue;
}
}