Package org.appfuse.webapp.client.application.base.activity

Source Code of org.appfuse.webapp.client.application.base.activity.AbstractProxySearchActivity

package org.appfuse.webapp.client.application.base.activity;

import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import javax.validation.ConstraintViolation;

import org.appfuse.webapp.client.application.Application;
import org.appfuse.webapp.client.application.base.place.EntityProxyPlace;
import org.appfuse.webapp.client.application.base.place.EntitySearchPlace;
import org.appfuse.webapp.client.application.base.view.ProxySearchView;
import org.appfuse.webapp.client.ui.home.HomePlace;

import com.google.gwt.activity.shared.Activity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.cellview.client.ColumnSortList;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.RangeChangeEvent;
import com.google.web.bindery.requestfactory.shared.BaseProxy;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;

/**
* Abstract activity for displaying a list of {@link EntityProxy}. These
* activities are not re-usable. Once they are stopped, they cannot be
* restarted.
* <p/>
* Subclasses must provide:
* <p/>
* <ul>
* <li>{@link #createView()}
* <li>{@link #createRequestContext()}
* <li>{@link #createCountRequest(RequestContext, BaseProxy)}
* <li>{@link #createSearchRequest(RequestContext, BaseProxy, Range, ColumnSortList)}
* </ul>
* <p/>
* Only the properties required by the view will be requested.
*
* @param <P> the type of {@link EntityProxy} listed
* @param <S> the type of {@link BaseProxy} acting as search criteria
*/
public abstract class AbstractProxySearchActivity<P extends EntityProxy, S> extends AbstractBaseActivity implements Activity, ProxySearchView.Delegate<P> {

    protected final Logger logger = Logger.getLogger(getClass().getName());

    private S searchCriteria;
    protected final Class<S> searchCriteriaType;
    protected final EntitySearchPlace currentPlace;

    protected ProxySearchView<P, S> view;
    private HandlerRegistration rangeChangeHandler;

    protected abstract RequestContext createRequestContext();
    protected abstract Request<Long> createCountRequest(RequestContext requestContext, S searchCriteria);
    protected abstract Request<List<P>> createSearchRequest(RequestContext requestContext, S searchCriteria, Range range, ColumnSortList columnSortList);


    public AbstractProxySearchActivity(final Application application, final ProxySearchView<P, S> view,
            final Class<S> searchCriteriaType) {
        super(application);
        this.currentPlace = (EntitySearchPlace) application.getPlaceController().getWhere();
        this.view = view;
        this.searchCriteriaType = searchCriteriaType;
    }

    @Override
    public void start(final AcceptsOneWidget panel, final EventBus eventBus) {
        view.setDelegate(this);
        panel.setWidget(view);
        setDocumentTitleAndBodyAttributtes();

        searchCriteria = (S) currentPlace.getSearchCriteria();
        if(searchCriteria == null) {
            searchCriteria = createSearchCriteria();
        }
        view.setSearchCriteria(searchCriteria);

        if(currentPlace.getMaxResults() > 0) {
            view.setPageSize(currentPlace.getMaxResults());
        }

        final HasData<P> hasData = view.asHasData();
        rangeChangeHandler = hasData.addRangeChangeHandler(new RangeChangeEvent.Handler() {
            @Override
            public void onRangeChange(final RangeChangeEvent event) {
                AbstractProxySearchActivity.this.onRangeChanged(hasData, hasData.getVisibleRange(), view.getColumnSortList());
            }
        });

        // Select the current page range to load (by default or from place tokens)
        Range range = hasData.getVisibleRange();
        if(currentPlace.getFirstResult() > 0 ||
                (currentPlace.getMaxResults() != range.getLength() && currentPlace.getMaxResults() > 0))
        {
            range = new Range(currentPlace.getFirstResult(), currentPlace.getMaxResults());
        }

        loadItems(searchCriteria, range);
    }

    protected S createSearchCriteria() {
        if(!String.class.equals(searchCriteriaType)) {
            return  (S) proxyFactory.create((Class<BaseProxy>)searchCriteriaType);
        }
        return null;
    }

    protected void loadItems(final S searchCriteria) {
        // Select the current page size to load
        final Range currentRange = view.asHasData().getVisibleRange();
        loadItems(searchCriteria, new Range(0, currentRange.getLength()));
    }

    /**
     * Load items on start.
     */
    protected void loadItems(final S searchCriteria, final Range range) {
        if(searchCriteria instanceof BaseProxy) {
            proxyFactory.setFrozen((BaseProxy) searchCriteria, true);
        }
        final RequestContext requestContext = createRequestContext();
        createCountRequest(requestContext, searchCriteria).fire(new Receiver<Long>() {
            @Override
            public void onSuccess(final Long response) {
                if (view == null) {
                    // This activity is dead
                    return;
                }
                view.asHasData().setRowCount(response.intValue(), true);
                onRangeChanged(view.asHasData(), range, view.getColumnSortList());
            }
        });
    }

    /**
     * Called by the table as it needs data.
     */
    protected void onRangeChanged(final HasData<P> hasData, final Range range, final ColumnSortList columnSortList) {
        final RequestContext requestContext = createRequestContext();
        createSearchRequest(requestContext, searchCriteria, range, columnSortList)
        .with(view.getPaths()).fire( new Receiver<List<P>>() {
            @Override
            public void onSuccess(final List<P> results) {
                if (view == null) {
                    // This activity is dead
                    return;
                }
                hasData.setRowData(range.getStart(), results);
                newHistoryToken(searchCriteria, range.getStart(), range.getLength());
            }
        });
    }

    protected void newHistoryToken(final S searchCriteria, final int firstResult, final int maxResults) {
        final String historyToken = new EntitySearchPlace.Tokenizer(proxyFactory, requests)
        .getFullHistoryToken(new EntitySearchPlace(currentPlace.getProxyClass(), firstResult, maxResults, searchCriteria));
        History.newItem(historyToken, false);
    }


    @Override
    public void addClicked() {
        placeController.goTo(new EntityProxyPlace(currentPlace.getProxyClass()));
    }

    @Override
    public void showDetails(final Class<? extends EntityProxy> proxyClass, final String entityId) {
        placeController.goTo(new EntityProxyPlace(proxyClass, entityId, EntityProxyPlace.Operation.EDIT));
    }

    @Override
    public void searchClicked() {
        if(searchCriteria instanceof BaseProxy) {
            proxyFactory.setFrozen((BaseProxy) searchCriteria, false);
        }
        searchCriteria = view.getSearchCriteria();
        final Set<ConstraintViolation<S>> violations = validate(searchCriteria);
        view.setConstraintViolations(violations);
        if(violations == null || violations.isEmpty()) {
            loadItems(searchCriteria);
        }
    }

    /**
     * Validates given searchCriteria.
     *
     * Override if you want to apply validation, example:
     * <code><pre>
     * protected Set<ConstraintViolation<S>> validate(S searchCriteria){
     *   return getValidator().validate(searchCriteria);
     * }
     * </pre></code>
     * @param searchCriteria
     * @return
     */
    protected Set<ConstraintViolation<S>> validate(final S searchCriteria){
        return null;//
    }

    @Override
    public void deleteClicked(final Class<? extends EntityProxy> proxyClass, final String entityId) {
        Window.alert("deleteClicked");
    }


    @Override
    public void cancelClicked() {
        placeController.goTo(new HomePlace());
    }


    @Override
    public void onCancel() {
        onStop();
    }

    @Override
    public void onStop() {
        view.setDelegate(null);
        view = null;
        rangeChangeHandler.removeHandler();
        rangeChangeHandler = null;
    }
}
TOP

Related Classes of org.appfuse.webapp.client.application.base.activity.AbstractProxySearchActivity

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.