Package org.pentaho.mantle.client.workspace

Source Code of org.pentaho.mantle.client.workspace.SchedulesPanel

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.mantle.client.workspace;

import static org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel.PAGE_SIZE;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.pentaho.gwt.widgets.client.dialogs.IDialogCallback;
import org.pentaho.gwt.widgets.client.dialogs.MessageDialogBox;
import org.pentaho.gwt.widgets.client.dialogs.PromptDialogBox;
import org.pentaho.gwt.widgets.client.toolbar.Toolbar;
import org.pentaho.gwt.widgets.client.toolbar.ToolbarButton;
import org.pentaho.gwt.widgets.client.utils.string.StringUtils;
import org.pentaho.mantle.client.commands.RefreshSchedulesCommand;
import org.pentaho.mantle.client.dialogs.scheduling.NewScheduleDialog;
import org.pentaho.mantle.client.dialogs.scheduling.OutputLocationUtils;
import org.pentaho.mantle.client.events.EventBusUtil;
import org.pentaho.mantle.client.events.GenericEvent;
import org.pentaho.mantle.client.images.ImageUtil;
import org.pentaho.mantle.client.messages.Messages;
import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel;
import org.pentaho.mantle.client.ui.PerspectiveManager;
import org.pentaho.mantle.client.workspace.SchedulesPerspectivePanel.CellTableResources;

import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestBuilder.Method;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.AbstractHeaderOrFooterBuilder;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.CellPreviewEvent;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;

public class SchedulesPanel extends SimplePanel {

  private static final int READ_PERMISSION = 0;

  private ToolbarButton controlScheduleButton = new ToolbarButton( ImageUtil.getThemeableImage( "icon-small",
      "icon-run" ) );
  private ToolbarButton editButton = new ToolbarButton( ImageUtil.getThemeableImage( "pentaho-editbutton" ) );
  private ToolbarButton triggerNowButton = new ToolbarButton( ImageUtil
      .getThemeableImage( "icon-small", "icon-execute" ) );
  private ToolbarButton scheduleRemoveButton =
      new ToolbarButton( ImageUtil.getThemeableImage( "pentaho-deletebutton" ) );
  private ToolbarButton filterButton =
      new ToolbarButton( ImageUtil.getThemeableImage( "icon-small", "icon-filter-add" ) );
  private ToolbarButton filterRemoveButton = new ToolbarButton( ImageUtil.getThemeableImage( "icon-small",
      "icon-filter-remove" ) );

  private JsArray<JsJob> allJobs;

  private ArrayList<IJobFilter> filters = new ArrayList<IJobFilter>();

  private CellTable<JsJob> table = new CellTable<JsJob>( PAGE_SIZE, (CellTableResources) GWT
      .create( CellTableResources.class ) );

  private ListDataProvider<JsJob> dataProvider = new ListDataProvider<JsJob>();

  private SimplePager pager;

  private FilterDialog filterDialog;

  private IDialogCallback filterDialogCallback = new IDialogCallback() {
    public void okPressed() {
      filters.clear();
      // create filters
      if ( filterDialog.getAfterDate() != null ) {
        filters.add( new IJobFilter() {
          public boolean accept( JsJob job ) {
            return job.getNextRun().after( filterDialog.getAfterDate() );
          }
        } );
      }
      if ( filterDialog.getBeforeDate() != null ) {
        filters.add( new IJobFilter() {
          public boolean accept( JsJob job ) {
            return job.getNextRun().before( filterDialog.getBeforeDate() );
          }
        } );
      }
      if ( !StringUtils.isEmpty( filterDialog.getResourceName() ) ) {
        filters.add( new IJobFilter() {
          public boolean accept( JsJob job ) {
            return job.getShortResourceName().toLowerCase().contains( filterDialog.getResourceName().toLowerCase() );
          }
        } );
      }
      final String showAll = Messages.getString( "showAll" );
      if ( !StringUtils.isEmpty( filterDialog.getUserFilter() ) && !filterDialog.getUserFilter().equals( showAll ) ) {
        filters.add( new IJobFilter() {
          public boolean accept( JsJob job ) {
            return job.getUserName().equalsIgnoreCase( filterDialog.getUserFilter() );
          }
        } );
      }
      if ( !StringUtils.isEmpty( filterDialog.getStateFilter() ) && !filterDialog.getStateFilter().equals( showAll ) ) {
        filters.add( new IJobFilter() {
          public boolean accept( JsJob job ) {
            return job.getState().toLowerCase().equalsIgnoreCase( filterDialog.getStateFilter() );
          }
        } );
      }
      if ( !StringUtils.isEmpty( filterDialog.getTypeFilter() ) && !filterDialog.getTypeFilter().equals( showAll ) ) {
        filters.add( new IJobFilter() {
          public boolean accept( JsJob job ) {
            return job.getJobTrigger().getScheduleType().equalsIgnoreCase( filterDialog.getTypeFilter() );
          }
        } );
      }
      filterRemoveButton.setEnabled( filters.size() > 0 );
      filterAndShowData();
    }

    public void cancelPressed() {
    }
  };

  @SuppressWarnings ( "unchecked" )
  private Set<JsJob> getSelectedJobs() {
    Set<JsJob> selectedJobs = ( (MultiSelectionModel<JsJob>) table.getSelectionModel() ).getSelectedSet();
    return selectedJobs;
  }

  private IDialogCallback scheduleDialogCallback = new IDialogCallback() {
    public void okPressed() {
      // Remove Next Line to disable deletion of old job
      controlJobs( getSelectedJobs(), "removeJob", RequestBuilder.DELETE, true );
      refresh();
    }

    public void cancelPressed() {
    }
  };

  public SchedulesPanel( final boolean isAdmin, final boolean isScheduler ) {
    createUI( isAdmin, isScheduler );
    refresh();
  }

  public void refresh() {
    String moduleBaseURL = GWT.getModuleBaseURL();
    String moduleName = GWT.getModuleName();
    String contextURL = moduleBaseURL.substring( 0, moduleBaseURL.lastIndexOf( moduleName ) );
    final String url = contextURL + "api/scheduler/jobs"; //$NON-NLS-1$
    RequestBuilder executableTypesRequestBuilder = new RequestBuilder( RequestBuilder.GET, url );
    executableTypesRequestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
    executableTypesRequestBuilder.setHeader( "accept", "application/json" );
    try {
      executableTypesRequestBuilder.sendRequest( null, new RequestCallback() {

        public void onError( Request request, Throwable exception ) {
          // showError(exception);
        }

        public void onResponseReceived( Request request, Response response ) {
          if ( response.getStatusCode() == Response.SC_OK ) {
            allJobs = parseJson( JsonUtils.escapeJsonForEval( response.getText() ) );
            filterAndShowData();
          }
        }
      } );
    } catch ( RequestException e ) {
      // showError(e);
    }
  }

  private void filterAndShowData() {

    filters.add( new IJobFilter() {
      public boolean accept( JsJob job ) {
        return !job.getFullResourceName().equals( "GeneratedContentCleaner" );
      }
    } );

    ArrayList<JsJob> filteredList = new ArrayList<JsJob>();
    for ( int i = 0; i < allJobs.length(); i++ ) {
      filteredList.add( allJobs.get( i ) );
      // filter if needed
      for ( IJobFilter filter : filters ) {
        if ( !filter.accept( allJobs.get( i ) ) ) {
          filteredList.remove( allJobs.get( i ) );
        }
      }
    }
    List<JsJob> list = dataProvider.getList();
    list.clear();
    list.addAll( filteredList );
    pager.setVisible( filteredList.size() > PAGE_SIZE );
    for ( JsJob job : filteredList ) {
      table.getSelectionModel().setSelected( job, false );
    }
    editButton.setEnabled( false );
    controlScheduleButton.setEnabled( false );
    scheduleRemoveButton.setEnabled( false );
    triggerNowButton.setEnabled( false );
    table.setPageStart( 0 );
    table.redraw();
  }

  private void
  updateControlSchedulerButtonState( final ToolbarButton controlSchedulerButton, final boolean isScheduler ) {
    final String url = GWT.getHostPageBaseURL() + "api/scheduler/state"; //$NON-NLS-1$
    RequestBuilder builder = new RequestBuilder( RequestBuilder.GET, url );
    builder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
    try {
      builder.sendRequest( null, new RequestCallback() {

        public void onError( Request request, Throwable exception ) {
          // showError(exception);
        }

        public void onResponseReceived( Request request, Response response ) {
          boolean isRunning = "RUNNING".equalsIgnoreCase( response.getText() );
          if ( isRunning ) {
            controlSchedulerButton.setToolTip( Messages.getString( "stopScheduler" ) );
            controlSchedulerButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-stop-scheduler" ) );
          } else {
            controlSchedulerButton.setToolTip( Messages.getString( "startScheduler" ) );
            controlSchedulerButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-start-scheduler" ) );
          }

          if ( !isScheduler ) {
            controlSchedulerButton.setEnabled( false );
          } else {
            controlSchedulerButton.setEnabled( true );
          }
        }
      } );
    } catch ( RequestException e ) {
      // showError(e);
    }
  }

  private void toggleSchedulerOnOff( final ToolbarButton controlSchedulerButton, final boolean isScheduler ) {
    final String url = GWT.getHostPageBaseURL() + "api/scheduler/state"; //$NON-NLS-1$
    RequestBuilder builder = new RequestBuilder( RequestBuilder.GET, url );
    builder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
    try {
      builder.sendRequest( null, new RequestCallback() {

        public void onError( Request request, Throwable exception ) {
          // showError(exception);
        }

        public void onResponseReceived( Request request, Response response ) {
          boolean isRunning = "RUNNING".equalsIgnoreCase( response.getText() );
          if ( isRunning ) {
            controlScheduler( controlSchedulerButton, "pause", isScheduler );
          } else {
            controlScheduler( controlSchedulerButton, "start", isScheduler );
          }
        }
      } );
    } catch ( RequestException e ) {
      // showError(e);
    }
  }

  private void createUI( boolean isAdmin, final boolean isScheduler ) {

    table.getElement().setId( "schedule-table" );
    table.setStylePrimaryName( "pentaho-table" );
    table.setWidth( "100%", true );

    // BISERVER-9331 Column sort indicators should be to the right of header text in the Manage Schedules table.
    if ( table.getHeaderBuilder() instanceof AbstractHeaderOrFooterBuilder ) {
      ( (AbstractHeaderOrFooterBuilder<JsJob>) table.getHeaderBuilder() ).setSortIconStartOfLine( false );
    }

    final MultiSelectionModel<JsJob> selectionModel = new MultiSelectionModel<JsJob>( new ProvidesKey<JsJob>() {
      public Object getKey( JsJob item ) {
        return item.getJobId();
      }
    } );
    table.setSelectionModel( selectionModel );

    Label noDataLabel = new Label( Messages.getString( "noSchedules" ) );
    noDataLabel.setStyleName( "noDataForScheduleTable" );
    table.setEmptyTableWidget( noDataLabel );

    TextColumn<JsJob> idColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        return job.getJobId();
      }
    };
    idColumn.setSortable( true );

    TextColumn<JsJob> nameColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        return job.getJobName();
      }
    };
    nameColumn.setSortable( true );

    TextColumn<JsJob> resourceColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        if ( job.getFullResourceName().contains( "." ) ) {
          return job.getFullResourceName().substring( 0, job.getFullResourceName().lastIndexOf( "." ) );
        } else {
          return job.getFullResourceName();
        }
      }
    };
    resourceColumn.setSortable( true );

    Column<JsJob, SafeHtml> outputPathColumn = new Column<JsJob, SafeHtml>( new ClickableSafeHtmlCell() ) {
      @Override
      public SafeHtml getValue( JsJob jsJob ) {
        try {
          String outputPath = jsJob.getOutputPath();
          if ( StringUtils.isEmpty( outputPath ) ) {
            return new SafeHtmlBuilder().appendHtmlConstant( "-" ).toSafeHtml();
          } else {
            return new SafeHtmlBuilder().appendHtmlConstant(
                "<span class='workspace-resource-link' title='"
                    + new SafeHtmlBuilder().appendEscaped( outputPath ).toSafeHtml().asString() + "'>" + outputPath
                    + "</span>"
            ).toSafeHtml();
          }
        } catch ( Throwable t ) {
          return new SafeHtmlBuilder().appendHtmlConstant( "-" ).toSafeHtml();
        }
      }
    };

    outputPathColumn.setFieldUpdater( new FieldUpdater<JsJob, SafeHtml>() {
      @Override
      public void update( final int index, final JsJob jsJob, final SafeHtml value ) {
        if ( !value.equals( "-" ) ) {

          final Command errorCallback = new Command() {
            @Override
            public void execute() {
              showValidateOutputLocationError();
            }
          };

          final Command successCallback = new Command() {
            @Override
            public void execute() {
              openOutputLocation( jsJob.getOutputPath() );
            }
          };

          OutputLocationUtils.validateOutputLocation( jsJob.getOutputPath(), successCallback, errorCallback );
        }
      }
    } );

    outputPathColumn.setSortable( true );

    TextColumn<JsJob> scheduleColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        try {
          return job.getJobTrigger().getDescription();
        } catch ( Throwable t ) {
          return "-";
        }
      }
    };
    scheduleColumn.setSortable( true );

    TextColumn<JsJob> userNameColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        try {
          return job.getUserName();
        } catch ( Throwable t ) {
          return "-";
        }
      }
    };
    userNameColumn.setSortable( true );

    TextColumn<JsJob> stateColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        try {
          // BISERVER-9965
          final String jobState = "COMPLETE".equalsIgnoreCase( job.getState() ) ? "FINISHED" : job.getState();
          // not css text-transform because tooltip will use pure text from the cell
          return jobState.substring( 0, 1 ).toUpperCase() + jobState.substring( 1 ).toLowerCase();
        } catch ( Throwable t ) {
          return "-";
        }
      }
    };
    stateColumn.setSortable( true );

    TextColumn<JsJob> nextFireColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        try {
          Date date = job.getNextRun();
          if ( date == null ) {
            return "-";
          }
          DateTimeFormat format = DateTimeFormat.getFormat( PredefinedFormat.DATE_TIME_MEDIUM );
          return format.format( date );
        } catch ( Throwable t ) {
          return "-";
        }
      }
    };
    nextFireColumn.setSortable( true );

    TextColumn<JsJob> lastFireColumn = new TextColumn<JsJob>() {
      public String getValue( JsJob job ) {
        try {
          Date date = job.getLastRun();
          if ( date == null ) {
            return "-";
          }
          DateTimeFormat format = DateTimeFormat.getFormat( PredefinedFormat.DATE_TIME_MEDIUM );
          return format.format( date );
        } catch ( Throwable t ) {
          return "-";
        }
      }
    };
    lastFireColumn.setSortable( true );

    // table.addColumn(idColumn, "ID");
    table.addColumn( nameColumn, Messages.getString( "scheduleName" ) );
    table.addColumn( scheduleColumn, Messages.getString( "recurrence" ) );
    table.addColumn( resourceColumn, Messages.getString( "sourceFile" ) );
    table.addColumn( outputPathColumn, Messages.getString( "outputPath" ) );

    table.addColumn( lastFireColumn, Messages.getString( "lastFire" ) );
    table.addColumn( nextFireColumn, Messages.getString( "nextFire" ) );
    if ( isAdmin ) {
      table.addColumn( userNameColumn, Messages.getString( "user" ) );
    }
    table.addColumn( stateColumn, Messages.getString( "state" ) );

    table.addColumnStyleName( 0, "backgroundContentHeaderTableCell" );
    table.addColumnStyleName( 1, "backgroundContentHeaderTableCell" );
    table.addColumnStyleName( 2, "backgroundContentHeaderTableCell" );
    table.addColumnStyleName( 3, "backgroundContentHeaderTableCell" );
    table.addColumnStyleName( 4, "backgroundContentHeaderTableCell" );
    table.addColumnStyleName( 5, "backgroundContentHeaderTableCell" );
    if ( isAdmin ) {
      table.addColumnStyleName( 6, "backgroundContentHeaderTableCell" );
    }
    table.addColumnStyleName( isAdmin ? 7 : 6, "backgroundContentHeaderTableCell" );

    table.setColumnWidth( nameColumn, 160, Unit.PX );
    table.setColumnWidth( resourceColumn, 200, Unit.PX );
    table.setColumnWidth( outputPathColumn, 180, Unit.PX );
    table.setColumnWidth( scheduleColumn, 170, Unit.PX );
    table.setColumnWidth( lastFireColumn, 120, Unit.PX );
    table.setColumnWidth( nextFireColumn, 120, Unit.PX );
    if ( isAdmin ) {
      table.setColumnWidth( userNameColumn, 100, Unit.PX );
    }
    table.setColumnWidth( stateColumn, 90, Unit.PX );

    dataProvider.addDataDisplay( table );
    List<JsJob> list = dataProvider.getList();

    ListHandler<JsJob> columnSortHandler = new ListHandler<JsJob>( list );

    columnSortHandler.setComparator( idColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 != null ) {
          return ( o2 != null ) ? o1.getJobId().compareTo( o2.getJobId() ) : 1;
        }
        return -1;
      }
    } );
    columnSortHandler.setComparator( nameColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 != null ) {
          return ( o2 != null ) ? o1.getJobName().compareTo( o2.getJobName() ) : 1;
        }
        return -1;
      }
    } );
    columnSortHandler.setComparator( resourceColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 != null ) {
          String r1 = o1.getShortResourceName();
          String r2 = null;
          if ( o2 != null ) {
            r2 = o2.getShortResourceName();
          }

          return ( o2 != null ) ? r1.compareTo( r2 ) : 1;
        }
        return -1;
      }
    } );
    columnSortHandler.setComparator( outputPathColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 != null ) {
          String r1 = o1.getOutputPath();
          String r2 = null;
          if ( o2 != null ) {
            r2 = o2.getOutputPath();
          }

          return ( o2 != null ) ? r1.compareTo( r2 ) : 1;
        }
        return -1;
      }
    } );
    columnSortHandler.setComparator( scheduleColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        String s1 = o1.getJobTrigger().getDescription();
        String s2 = o2.getJobTrigger().getDescription();
        return s1.compareTo( s2 );
      }
    } );
    columnSortHandler.setComparator( userNameColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 != null ) {
          return ( o2 != null ) ? o1.getUserName().compareTo( o2.getUserName() ) : 1;
        }
        return -1;
      }
    } );
    columnSortHandler.setComparator( stateColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 != null ) {
          return ( o2 != null ) ? o1.getState().compareTo( o2.getState() ) : 1;
        }
        return -1;
      }
    } );
    columnSortHandler.setComparator( nextFireColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 == null || o1.getNextRun() == null ) {
          return -1;
        }
        if ( o2 == null || o2.getNextRun() == null ) {
          return 1;
        }

        if ( o1.getNextRun() == o2.getNextRun() ) {
          return 0;
        }

        return o1.getNextRun().compareTo( o2.getNextRun() );
      }
    } );
    columnSortHandler.setComparator( lastFireColumn, new Comparator<JsJob>() {
      public int compare( JsJob o1, JsJob o2 ) {
        if ( o1 == o2 ) {
          return 0;
        }

        if ( o1 == null || o1.getLastRun() == null ) {
          return -1;
        }
        if ( o2 == null || o2.getLastRun() == null ) {
          return 1;
        }

        if ( o1.getLastRun() == o2.getLastRun() ) {
          return 0;
        }

        return o1.getLastRun().compareTo( o2.getLastRun() );
      }
    } );
    table.addColumnSortHandler( columnSortHandler );

    table.getColumnSortList().push( idColumn );
    table.getColumnSortList().push( resourceColumn );
    table.getColumnSortList().push( outputPathColumn );
    table.getColumnSortList().push( nameColumn );

    table.getSelectionModel().addSelectionChangeHandler( new Handler() {
      public void onSelectionChange( SelectionChangeEvent event ) {
        Set<JsJob> selectedJobs = getSelectedJobs();
        if ( selectedJobs != null && selectedJobs.size() > 0 ) {
          JsJob[] jobs = selectedJobs.toArray( new JsJob[selectedJobs.size()] );
          editButton.setEnabled( isScheduler );
          if ( "NORMAL".equalsIgnoreCase( jobs[0].getState() ) ) {
            controlScheduleButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-stop" ) );
          } else {
            controlScheduleButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-run" ) );
          }
          controlScheduleButton.setEnabled( isScheduler );

          boolean isRunning = "NORMAL".equalsIgnoreCase( jobs[0].getState() );
          controlScheduleButton.setToolTip( isRunning ? Messages.getString( "stop" ) : Messages.getString( "start" ) );
          scheduleRemoveButton.setEnabled( isScheduler );
          triggerNowButton.setEnabled( isScheduler );
        } else {
          editButton.setEnabled( false );
          controlScheduleButton.setEnabled( false );
          scheduleRemoveButton.setEnabled( false );
          triggerNowButton.setEnabled( false );
        }
      }
    } );
    // BISERVER-9965
    table.addCellPreviewHandler( new CellPreviewEvent.Handler<JsJob>() {
      @Override
      public void onCellPreview( CellPreviewEvent<JsJob> event ) {
        if ( "mouseover".equals( event.getNativeEvent().getType() ) ) {
          final TableCellElement cell = table.getRowElement( event.getIndex() ).getCells().getItem( event.getColumn() );
          cell.setTitle( cell.getInnerText() );
        }
      }
    } );

    SimplePager.Resources pagerResources = GWT.create( SimplePager.Resources.class );
    pager = new SimplePager( TextLocation.CENTER, pagerResources, false, 0, true ) {
      @Override
      public void setPageStart( int index ) {
        if ( getDisplay() != null ) {
          Range range = getDisplay().getVisibleRange();
          int pageSize = range.getLength();

          // Removed the min to show fixed ranges
          // if (isRangeLimited && display.isRowCountExact()) {
          // index = Math.min(index, display.getRowCount() - pageSize);
          // }

          index = Math.max( 0, index );
          if ( index != range.getStart() ) {
            getDisplay().setVisibleRange( index, pageSize );
          }
        }
      }
    };
    pager.setDisplay( table );
    // pager.setRangeLimited(false);

    VerticalPanel tableAndPager = new VerticalPanel();
    tableAndPager.setHorizontalAlignment( HasHorizontalAlignment.ALIGN_CENTER );

    Toolbar bar = new Toolbar();
    bar.addSpacer( 10 );

    bar.add( Toolbar.GLUE );

    // Add control scheduler button
    if ( isAdmin ) {
      final ToolbarButton controlSchedulerButton =
          new ToolbarButton( ImageUtil.getThemeableImage( "icon-small", "icon-start-scheduler" ) );

      controlSchedulerButton.setCommand( new Command() {
        public void execute() {
          toggleSchedulerOnOff( controlSchedulerButton, isScheduler );
        }
      } );
      updateControlSchedulerButtonState( controlSchedulerButton, isScheduler );

      bar.add( controlSchedulerButton );
      bar.addSpacer( 20 );
    }

    // Add filter button
    filterButton.setCommand( new Command() {
      public void execute() {
        if ( filterDialog == null ) {
          filterDialog = new FilterDialog( allJobs, filterDialogCallback );
        } else {
          filterDialog.initUI( allJobs );
        }
        filterDialog.center();
      }
    } );
    filterButton.setToolTip( Messages.getString( "filterSchedules" ) );
    if ( isAdmin ) {
      bar.add( filterButton );
    }

    // Add remove filters button
    filterRemoveButton.setCommand( new Command() {
      public void execute() {
        filterDialog = null;
        filters.clear();
        filterAndShowData();
        filterRemoveButton.setEnabled( false );
        filterButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-filter-add" ) );
      }
    } );
    filterRemoveButton.setToolTip( Messages.getString( "removeFilters" ) );
    filterRemoveButton.setEnabled( filters.size() > 0 );
    if ( isAdmin ) {
      bar.add( filterRemoveButton );
    }

    // Add refresh button
    ToolbarButton refresh = new ToolbarButton( ImageUtil.getThemeableImage( "icon-small", "icon-refresh" ) );
    refresh.setToolTip( Messages.getString( "refreshTooltip" ) );
    refresh.setCommand( new Command() {
      public void execute() {
        RefreshSchedulesCommand cmd = new RefreshSchedulesCommand();
        cmd.execute();
      }
    } );
    bar.add( refresh );

    bar.addSpacer( 20 );

    // Add execute now button
    triggerNowButton.setToolTip( Messages.getString( "executeNow" ) );
    triggerNowButton.setCommand( new Command() {
      public void execute() {
        Set<JsJob> selectedJobs = getSelectedJobs();
        if ( selectedJobs != null && selectedJobs.size() > 0 ) {
          MessageDialogBox messageDialog =
              new MessageDialogBox( Messages.getString( "executeNow" ), Messages.getString( "executeNowStarted" ),
                  false, true, true );
          messageDialog.setCallback( new IDialogCallback() {
            public void okPressed() {
              // wait a little to refresh to give schedule time to update the last run
              Timer t = new Timer() {
                public void run() {
                  refresh();
                }
              };
              t.schedule( 2000 );
            }

            public void cancelPressed() {
            }
          } );
          messageDialog.center();
          controlJobs( selectedJobs, "triggerNow", RequestBuilder.POST, false );
        }
      }
    } );
    triggerNowButton.setEnabled( false );
    bar.add( triggerNowButton );

    // Add control schedule button
    controlScheduleButton.setCommand( new Command() {
      public void execute() {
        Set<JsJob> selectedJobs = getSelectedJobs();
        if ( selectedJobs != null && selectedJobs.size() > 0 ) {
          JsJob[] jobs = selectedJobs.toArray( new JsJob[selectedJobs.size()] );
          if ( "NORMAL".equals( jobs[0].getState() ) ) {
            controlJobs( selectedJobs, "pauseJob", RequestBuilder.POST, false );
          } else {
            controlJobs( selectedJobs, "resumeJob", RequestBuilder.POST, false );
          }
        }
      }
    } );
    controlScheduleButton.setEnabled( false );
    bar.add( controlScheduleButton );

    bar.addSpacer( 20 );

    // Add edit button
    editButton.setCommand( new Command() {
      public void execute() {
        Set<JsJob> selectedJobs = getSelectedJobs();
        if ( selectedJobs != null && selectedJobs.size() > 0 ) {
          JsJob[] jobs = selectedJobs.toArray( new JsJob[selectedJobs.size()] );
          final JsJob editJob = jobs[0];
          final String url =
              GWT.getHostPageBaseURL() + "api/repo/files/"
                  + SolutionBrowserPanel.pathToId( editJob.getFullResourceName() ) + "/canAccess?cb="
                  + System.currentTimeMillis() + "&permissions=" + READ_PERMISSION;
          RequestBuilder executableTypesRequestBuilder = new RequestBuilder( RequestBuilder.GET, url );
          try {
            executableTypesRequestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
            executableTypesRequestBuilder.sendRequest( null, new RequestCallback() {

              public void onError( Request request, Throwable exception ) {
                promptForScheduleResourceError( editJob );
              }

              public void onResponseReceived( Request request, Response response ) {
                if ( "true".equalsIgnoreCase( response.getText() ) ) {
                  editJob( editJob );
                } else {
                  promptForScheduleResourceError( editJob );
                }
              }
            } );
          } catch ( RequestException e ) {
            // showError(e);
          }
        }
      }
    } );

    editButton.setEnabled( false );
    editButton.setToolTip( Messages.getString( "editTooltip" ) );
    bar.add( editButton );

    // Add remove button
    scheduleRemoveButton.setCommand( new Command() {
      public void execute() {
        Set<JsJob> selectedJobs = getSelectedJobs();
        if ( selectedJobs != null && selectedJobs.size() > 0 ) {
          final PromptDialogBox prompt =
              new PromptDialogBox( Messages.getString( "warning" ), Messages.getString( "yes" ), Messages
                  .getString( "no" ), false, true );
          prompt.setContent( new Label( Messages.getString( "deleteConfirmSchedles", "" + selectedJobs.size() ) ) );

          prompt.setCallback( new IDialogCallback() {
            public void okPressed() {
              controlJobs( getSelectedJobs(), "removeJob", RequestBuilder.DELETE, true );
              prompt.hide();
            }

            public void cancelPressed() {
              prompt.hide();
            }
          } );
          prompt.center();
        }
      }
    } );
    scheduleRemoveButton.setToolTip( Messages.getString( "remove" ) );
    scheduleRemoveButton.setEnabled( false );
    bar.add( scheduleRemoveButton );

    tableAndPager.add( bar );
    tableAndPager.add( table );
    tableAndPager.add( pager );

    // Add it to the root panel.
    setWidget( tableAndPager );
  }

  private void editJob( JsJob editJob ) {
    final String url = GWT.getHostPageBaseURL() + "api/scheduler/jobinfo?jobId=" + URL.encodeQueryString( editJob.getJobId() );
    RequestBuilder executableTypesRequestBuilder = new RequestBuilder( RequestBuilder.GET, url );
    executableTypesRequestBuilder.setHeader( "accept", "application/json" );
    executableTypesRequestBuilder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
    try {
      executableTypesRequestBuilder.sendRequest( null, new RequestCallback() {

        public void onError( Request request, Throwable exception ) {
          // showError(exception);
        }

        public void onResponseReceived( Request request, Response response ) {
          if ( response.getStatusCode() == Response.SC_OK ) {
            final JsJob jsJob = parseJsonJob( JsonUtils.escapeJsonForEval( response.getText() ) );

            // check email is setup
            RequestBuilder emailValidRequest =
                new RequestBuilder( RequestBuilder.GET, GWT.getHostPageBaseURL() + "api/emailconfig/isValid" );
            emailValidRequest.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
            emailValidRequest.setHeader( "accept", "text/plain" );
            try {
              emailValidRequest.sendRequest( null, new RequestCallback() {

                public void onError( Request request, Throwable exception ) {
                  MessageDialogBox dialogBox =
                      new MessageDialogBox( Messages.getString( "error" ), exception.toString(), false, false, true ); //$NON-NLS-1$
                  dialogBox.center();
                }

                public void onResponseReceived( Request request, Response response ) {
                  if ( response.getStatusCode() == Response.SC_OK ) {
                    final boolean isEmailConfValid = Boolean.parseBoolean( response.getText() );
                    final NewScheduleDialog schedDialog =
                        new NewScheduleDialog( jsJob, scheduleDialogCallback, isEmailConfValid );
                    schedDialog.center();
                  }
                }
              } );
            } catch ( RequestException e ) {
              // showError(e);
            }

          } else {
            MessageDialogBox dialogBox =
                new MessageDialogBox(
                    Messages.getString( "error" ), Messages.getString( "serverErrorColon" ) + " " + response.getStatusCode(), false, false, true ); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
            dialogBox.center();
          }
        }
      } );
    } catch ( RequestException e ) {
      // showError(e);
    }
  }

  private void promptForScheduleResourceError( final JsJob job ) {
    final PromptDialogBox prompt =
        new PromptDialogBox( Messages.getString( "fileUnavailable" ), Messages.getString( "yesDelete" ), Messages
            .getString( "no" ), false, true );
    prompt.setContent( new HTML( Messages.getString( "editScheduleResourceDoesNotExist",
        job.getFullResourceName() ) ) );

    prompt.setCallback( new IDialogCallback() {
      public void okPressed() {
        HashSet<JsJob> jobSet = new HashSet<JsJob>();
        jobSet.add( job );
        controlJobs( jobSet, "removeJob", RequestBuilder.DELETE, true );
        prompt.hide();
      }

      public void cancelPressed() {
        prompt.hide();
      }
    } );
    prompt.setWidth( "530px" );
    prompt.center();
  }

  private void controlJobs( final Set<JsJob> jobs, String function, final Method method, final boolean refreshData ) {
    for ( final JsJob job : jobs ) {
      final String url = GWT.getHostPageBaseURL() + "api/scheduler/" + function; //$NON-NLS-1$
      RequestBuilder builder = new RequestBuilder( method, url );
      builder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
      builder.setHeader( "Content-Type", "application/json" ); //$NON-NLS-1$//$NON-NLS-2$

      JSONObject startJobRequest = new JSONObject();
      startJobRequest.put( "jobId", new JSONString( job.getJobId() ) ); //$NON-NLS-1$

      try {
        builder.sendRequest( startJobRequest.toString(), new RequestCallback() {

          public void onError( Request request, Throwable exception ) {
            // showError(exception);
          }

          public void onResponseReceived( Request request, Response response ) {
            job.setState( response.getText() );
            table.redraw();
            boolean isRunning = "NORMAL".equalsIgnoreCase( response.getText() );
            if ( isRunning ) {
              controlScheduleButton.setToolTip( Messages.getString( "stop" ) );
              controlScheduleButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-stop" ) );
            } else {
              controlScheduleButton.setToolTip( Messages.getString( "start" ) );
              controlScheduleButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-run" ) );
            }
            if ( refreshData ) {
              refresh();
            }
          }
        } );
      } catch ( RequestException e ) {
        // showError(e);
      }
    }
  }

  private void controlScheduler( final ToolbarButton controlSchedulerButton, final String function,
                                 final boolean isScheduler ) {
    final String url = GWT.getHostPageBaseURL() + "api/scheduler/" + function; //$NON-NLS-1$
    RequestBuilder builder = new RequestBuilder( RequestBuilder.POST, url );
    builder.setHeader( "If-Modified-Since", "01 Jan 1970 00:00:00 GMT" );
    try {
      builder.sendRequest( null, new RequestCallback() {

        public void onError( Request request, Throwable exception ) {
          // showError(exception);
        }

        public void onResponseReceived( Request request, Response response ) {
          boolean isRunning = "RUNNING".equalsIgnoreCase( response.getText() );
          if ( isRunning ) {
            controlSchedulerButton.setToolTip( Messages.getString( "stopScheduler" ) );
            controlSchedulerButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-stop-scheduler" ) );
          } else {
            controlSchedulerButton.setToolTip( Messages.getString( "startScheduler" ) );
            controlSchedulerButton.setImage( ImageUtil.getThemeableImage( "icon-small", "icon-start-scheduler" ) );
          }

          if ( !isScheduler ) {
            controlSchedulerButton.setEnabled( false );
          } else {
            controlSchedulerButton.setEnabled( true );
          }
        }
      } );
    } catch ( RequestException e ) {
      // showError(e);
    }
  }

  private void openOutputLocation( final String outputLocation ) {
    final String url = GWT.getHostPageBaseURL() + "api/mantle/session-variable?key=scheduler_folder&value=" + outputLocation;
    PerspectiveManager.getInstance().setPerspective( PerspectiveManager.BROWSER_PERSPECTIVE );
    RequestBuilder executableTypesRequestBuilder = new RequestBuilder( RequestBuilder.POST, url );
    try {
      executableTypesRequestBuilder.sendRequest( null, new RequestCallback() {
        public void onError( Request request, Throwable exception ) {
        }

        public void onResponseReceived( Request request, Response response ) {
        }
      } );
    } catch ( RequestException e ) {
      //IGNORE
    }
    GenericEvent event = new GenericEvent();
    event.setEventSubType( "RefreshFolderEvent" );
    event.setStringParam( outputLocation );
    EventBusUtil.EVENT_BUS.fireEvent( event );
  }

  private void showValidateOutputLocationError() {
    String title = Messages.getString( "outputLocationErrorTitle" );
    String message = Messages.getString( "outputLocationErrorMessage" );
    MessageDialogBox dialogBox =
        new MessageDialogBox( title, message, false, false, true, Messages.getString( "close" ), null, null ); //$NON-NLS-1$
    dialogBox.addStyleName( "pentaho-dialog-small" );
    dialogBox.center();
  }

  private native JsArray<JsJob> parseJson( String json )
  /*-{
      var obj = eval('(' + json + ')');
      if (obj != null && obj.hasOwnProperty("job")) {
          return obj.job;
      }
      return [];
  }-*/;

  private native JsJob parseJsonJob( String json )
  /*-{
      var obj = eval('(' + json + ')');
      return obj;
  }-*/;

TOP

Related Classes of org.pentaho.mantle.client.workspace.SchedulesPanel

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.