/*
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.server.headlessclient.dataui;
import java.awt.Event;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.wicket.Component;
import org.apache.wicket.model.AbstractWrapModel;
import org.apache.wicket.model.IComponentAssignedModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.IWrapModel;
import org.apache.wicket.model.Model;
import com.servoy.j2db.FormController;
import com.servoy.j2db.component.ComponentFactory;
import com.servoy.j2db.dataprocessing.DBValueList;
import com.servoy.j2db.dataprocessing.FoundSet;
import com.servoy.j2db.dataprocessing.FoundSetListWrapper;
import com.servoy.j2db.dataprocessing.FoundSetManager;
import com.servoy.j2db.dataprocessing.SortColumn;
import com.servoy.j2db.persistence.AbstractBase;
import com.servoy.j2db.persistence.Form;
import com.servoy.j2db.persistence.GraphicalComponent;
import com.servoy.j2db.persistence.IColumnTypes;
import com.servoy.j2db.persistence.IDataProvider;
import com.servoy.j2db.persistence.IPersist;
import com.servoy.j2db.persistence.ISupportDataProviderID;
import com.servoy.j2db.persistence.ISupportName;
import com.servoy.j2db.persistence.Portal;
import com.servoy.j2db.persistence.RepositoryException;
import com.servoy.j2db.persistence.Table;
import com.servoy.j2db.scripting.JSEvent;
import com.servoy.j2db.server.headlessclient.WebForm;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.ScopesUtils;
import com.servoy.j2db.util.Utils;
/**
* A model sorts a {@link WebCellBasedView} and keeps the sort state.
*
* @author jblok
*/
public class SortableCellViewHeaderGroup extends Model implements IComponentAssignedModel
{
private static final long serialVersionUID = 1L;
final private Map<String, Boolean> sorted = new HashMap<String, Boolean>();
final private ServoyListView listView;
final private AbstractBase cellview;
final private Form form;
public SortableCellViewHeaderGroup(Form form, final ServoyListView listView, AbstractBase cellview)
{
this.listView = listView;
this.cellview = cellview;
this.form = form;
}
public Boolean get(String name)
{
return sorted.get(name);
}
/**
* @see wicket.model.IAssignmentAwareModel#wrapOnAssignment(wicket.Component)
*/
public IWrapModel wrapOnAssignment(Component component)
{
return new WrapModel(component);
}
private boolean direction;
public int getSortDirection()
{
return direction ? SortColumn.ASCENDING : SortColumn.DESCENDING;
}
public void recordSort(Map<String, Boolean> sortMap)
{
sorted.clear();
sorted.putAll(sortMap);
}
protected final void sort(final String name, final WebCellBasedView view, int modifiers)
{
direction = Utils.getAsBoolean(sorted.get(name));
direction = !direction;
try
{
Iterator<IPersist> it = cellview.getAllObjects();
while (it.hasNext())
{
IPersist element = it.next();
if (element instanceof ISupportName && element instanceof ISupportDataProviderID)
{
if (name.equals(ComponentFactory.getWebID(form, element)))
{
FoundSet fs = ((FoundSetListWrapper)listView.getList()).getFoundSet();
if (fs != null)
{
WebForm wf = listView.findParent(WebForm.class);
FormController fc = null;
if (wf != null) fc = wf.getController();
GraphicalComponent gc = (GraphicalComponent)view.labelsFor.get(((ISupportName)element).getName());
int labelForOnActionMethodId = 0;
if (gc != null)
{
labelForOnActionMethodId = gc.getOnActionMethodID();
}
if (fc != null && labelForOnActionMethodId > 0)
{ //execute on action
JSEvent event = new JSEvent();
event.setType(JSEvent.EventType.action);
event.setFormName(view.getDataAdapterList().getFormController().getName());
event.setModifiers(modifiers);
event.setElementName(gc.getName());
fc.executeFunction(
String.valueOf(labelForOnActionMethodId),
Utils.arrayMerge((new Object[] { event }), Utils.parseJSExpressions(gc.getInstanceMethodArguments("onActionMethodID"))), true, null, false, "onActionMethodID"); //$NON-NLS-1$ //$NON-NLS-2$
}
String id = ((ISupportDataProviderID)element).getDataProviderID();
if (id != null)
{
if (cellview instanceof Portal && !ScopesUtils.isVariableScope(id))
{
int idx = id.lastIndexOf('.');
if (idx > 0)
{
id = id.substring(idx + 1);
}
}
IDataProvider dataProvider = null;
if (fc != null)
{
dataProvider = fs.getFoundSetManager().getApplication().getFlattenedSolution().getDataproviderLookup(
fs.getFoundSetManager(), fc.getForm()).getDataProvider(id);
}
if (!(fc != null && labelForOnActionMethodId > 0))
{ // in case there is no onAction definned
if (cellview instanceof Portal || fc == null || fc.getForm().getOnSortCmdMethodID() == 0)
{
List<String> sortingProviders = null;
try
{
sortingProviders = DBValueList.getShowDataproviders(
fs.getFoundSetManager().getApplication().getFlattenedSolution().getValueList(
((ISupportDataProviderID)element).getValuelistID()), (Table)fs.getTable(), dataProvider == null ? id
: dataProvider.getDataProviderID(), fs.getFoundSetManager());
}
catch (RepositoryException ex)
{
Debug.error(ex);
}
if (sortingProviders == null)
{
// no related sort, use sort on dataProviderID instead
sortingProviders = Collections.singletonList(dataProvider == null ? id : dataProvider.getDataProviderID());
}
List<SortColumn> list = (modifiers & Event.SHIFT_MASK) != 0 ? fs.getSortColumns() : new ArrayList<SortColumn>();
for (String sortingProvider : sortingProviders)
{
FoundSetManager fsm = (FoundSetManager)fs.getFoundSetManager();
SortColumn sc = fsm.getSortColumn(fs.getTable(), sortingProvider, false);
if (sc != null && sc.getColumn().getDataProviderType() != IColumnTypes.MEDIA)
{
for (SortColumn oldColumn : list)
{
if (oldColumn.equalsIgnoreSortorder(sc))
{
sc = oldColumn;
break;
}
}
if (!list.contains(sc)) list.add(sc);
sc.setSortOrder(direction ? SortColumn.ASCENDING : SortColumn.DESCENDING);
}
fs.sort(list, false);
}
}
else if (fc != null && fc.getForm().getOnSortCmdMethodID() != -1)
{
JSEvent event = new JSEvent();
event.setType(JSEvent.EventType.none);
event.setFormName(view.getDataAdapterList().getFormController().getName());
event.setModifiers(modifiers);
fc.executeFunction(
String.valueOf(fc.getForm().getOnSortCmdMethodID()),
Utils.arrayMerge(
(new Object[] { dataProvider == null ? id : dataProvider.getDataProviderID(), Boolean.valueOf(direction), event }),
Utils.parseJSExpressions(fc.getForm().getInstanceMethodArguments("onSortCmdMethodID"))), true, null, false, "onSortCmdMethodID"); //$NON-NLS-1$//$NON-NLS-2$
}
}
if ((modifiers & Event.SHIFT_MASK) == 0)
{
sorted.clear();
}
sorted.put(name, new Boolean(direction));
listView.setCurrentPage(0);
}
}
break;
}
}
}
listView.modelChanged();
}
catch (Exception e)
{
Debug.error(e);
}
}
class WrapModel extends AbstractWrapModel
{
private static final long serialVersionUID = 1L;
private final Component component;
WrapModel(Component component)
{
this.component = component;
}
/**
* @see wicket.model.IWrapModel#getNestedModel()
*/
public IModel getWrappedModel()
{
return SortableCellViewHeaderGroup.this;
}
@Override
public void detach()
{
SortableCellViewHeaderGroup.this.detach();
}
/**
* @see wicket.model.IModel#getObject()
*/
@Override
public Object getObject()
{
Boolean dir = sorted.get(component.getParent().getId());
if (dir != null)
{
return (dir.booleanValue() ? "orderAsc" : "orderDesc"); //$NON-NLS-1$ //$NON-NLS-2$
}
return null;
}
}
}