/*
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.dataprocessing;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.Utils;
/**
* This class handles the updates based on change being done on LH side of a relation used for lookups, and will inform the DAL about refreshes
*
* @author jblok
*/
public class RelookupAdapter implements IDataAdapter
{
//representing dataprovider
private final Set<String> dataProviderIDs;
private final String dataProviderIDToLookup;
private final List<String> dataProviderIDsToSet;
private final DataAdapterList list;//parent
private IRecordInternal state;//state to lookup in.
public RelookupAdapter(DataAdapterList list, String dataProviderIDToSet, String dataProviderIDToLookup, Set<String> dataProviderIDs)
{
this.list = list;
this.dataProviderIDsToSet = new ArrayList<String>(1);
this.dataProviderIDsToSet.add(dataProviderIDToSet);
this.dataProviderIDToLookup = dataProviderIDToLookup;
this.dataProviderIDs = dataProviderIDs;
if (Debug.tracing())
{
Debug.trace("Created lookup adapter on " + dataProviderIDToSet + " from " + dataProviderIDToLookup); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/*
* @see IDataAdapter#setState(State)
*/
public void setRecord(IRecordInternal s)
{
if (s != state)
{
this.state = s;
if (s == null || s instanceof PrototypeState)
{
oldValues.clear();
}
else
{
Iterator<String> it = dataProviderIDs.iterator();
while (it.hasNext())
{
String dataprovider = it.next();
oldValues.put(dataprovider, s.getValue(dataprovider));
}
}
}
}
/*
* @see IDataAdapter#getDataProviderID()
*/
public String getDataProviderID()
{
return null;
}
/*
* _____________________________________________________________ DataListener
*/
private final ArrayList<IDataAdapter> listeners = new ArrayList<IDataAdapter>();
public void addDataListener(IDataAdapter l)
{
if (!listeners.contains(l) && l != this) listeners.add(l);
}
public void removeDataListener(IDataAdapter listener)
{
listeners.remove(listener);
}
public void displayValueChanged(ModificationEvent event)
{
valueChangedImpl(event);
}
public void valueChanged(ModificationEvent e)
{
valueChangedImpl(e);
}
/*
* _____________________________________________________________ JavaScriptModificationLisetner
*/
private final HashMap<String, Object> oldValues = new HashMap<String, Object>(5);
private void valueChangedImpl(ModificationEvent e)
{
if (!findMode && (e.getRecord() == null || e.getRecord() == state) && dataProviderIDs.contains(e.getName()) && !(state instanceof PrototypeState))
{
Object oldValue = oldValues.get(e.getName());
if (!Utils.equalObjects(oldValue, e.getValue()))
{
if (Debug.tracing())
{
Debug.trace("Executing lookup on " + dataProviderIDsToSet + " from " + dataProviderIDToLookup + " with value " + e.getValue()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
oldValues.put(e.getName(), e.getValue());
Object obj = state.getValue(dataProviderIDToLookup);
// TODO CHECK this is disabled because if there are more then 1 relookup adapter then for every change an update will be generated
// and so on and so on. Relookup just starts it now And blow this call there should be a stopEditing (see Record.fireJSModxxxx)
// But currently if this is a global change then the record stays a bit longer in edit mode (until a stop global editing happens)
if (state.startEditing()) //make sure this change is noted!
{
for (int i = 0; i < dataProviderIDsToSet.size(); i++)
{
String dataprovider = dataProviderIDsToSet.get(i);
Object oldVal = state.setValue(dataprovider, obj);
if (oldVal != obj) list.valueChanged(new ModificationEvent(dataprovider, obj, state));
}
}
}
}
}
public IDisplayRelatedData getDisplay()
{
return null;
}
private boolean findMode;
public void setFindMode(boolean b)
{
findMode = b;
}
@Override
public String toString()
{
return "RelookupAdapter lookup on " + dataProviderIDsToSet + " from " + dataProviderIDToLookup + ", hash " + hashCode(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void addDataProviderId(String dataProviderID)
{
dataProviderIDsToSet.add(dataProviderID);
}
}