gt:     return PentahoSystem.get( IAuthorizationPolicy.class );
context: /*!
   * Copyright 2002 - 2019 Webdetails, a Hitachi Vantara company. All rights reserved.
   *
   * This software was developed by Webdetails and is provided under the terms
   * of the Mozilla Public License, Version 2.0, or any later version. You may not use
   * this file except in compliance with the license. If you need a copy of the license,
   * please go to  http://mozilla.org/MPL/2.0/. The Initial Developer is Webdetails.
   *
   * Software distributed under the Mozilla Public License is distributed on an "AS IS"
   * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
   * the license for the specific language governing your rights and limitations.
   */
  
  package pt.webdetails.cda.cache.scheduler;
  
  import java.io.IOException;
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  
  import org.apache.commons.lang.StringUtils;
  import org.apache.commons.logging.Log;
  import com.fasterxml.jackson.core.JsonGenerator;
  import org.json.JSONException;
  import org.json.JSONObject;
  import org.pentaho.platform.api.engine.IAuthorizationPolicy;
  import org.pentaho.platform.api.engine.IPentahoSession;
  import org.pentaho.platform.api.scheduler2.IJobFilter;
  import org.pentaho.platform.api.scheduler2.IJobTrigger;
  import org.pentaho.platform.api.scheduler2.IScheduler;
  import org.pentaho.platform.api.scheduler2.Job;
  import org.pentaho.platform.api.scheduler2.Job.JobState;
  import org.pentaho.platform.api.scheduler2.SchedulerException;
  import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
  import org.pentaho.platform.engine.core.system.PentahoSystem;
  import org.pentaho.platform.scheduler2.quartz.QuartzScheduler;
  import org.pentaho.platform.security.policy.rolebased.actions.SchedulerAction;
  
  import pt.webdetails.cda.AccessDeniedException;
  import pt.webdetails.cda.CdaEngine;
  import pt.webdetails.cda.dataaccess.Parameter;
  import pt.webdetails.cda.query.QueryOptions;
  import pt.webdetails.cda.services.BaseService;
  import pt.webdetails.cda.settings.CdaSettings;
  import pt.webdetails.cda.settings.SettingsManager;
  import pt.webdetails.cda.utils.PentahoHelper;
  import pt.webdetails.cpf.messaging.JsonGeneratorSerializable;
  
  public class CdaCacheScheduler extends BaseService {
  
    private static final String JOB_NAME_PREFIX = "CDA-sched/";
    private static final String SUGAR_SCHEDULER_BEAN_ID = "IScheduler2";
    private static final String ACTION_BEAN_ID = "CdaCacheWarmup";
  
    private static final String STATUS_OK = "ok";
    private static final String STATUS_ERROR = "error";
    private static final String STATUS_FIELD = "status";
  
  
    public JsonGeneratorSerializable scheduleQueryExecution( String jsonString ) {
  
      try {
        QueryExecution query = new QueryExecution( getSettingsManager(), jsonString );
        checkSchedulerAccess( query, PentahoSessionHolder.getSession() );
        final Job job = scheduleQuery( query );
        if ( job != null ) {
          logJob( job );
          return new JsonGeneratorSerializable() {
  
            public void writeToGenerator( JsonGenerator out ) throws IOException {
              out.writeStartObject();
              out.writeStringField( STATUS_FIELD, STATUS_OK );
              out.writeStringField( "jobId", job.getJobId() );
              out.writeEndObject();
            }
          };
        }
      } catch ( Exception e ) {
        getLog().error( e );
        return getError( e );
      }
      return null;
    }
  
    public JsonGeneratorSerializable deleteJob( String id ) {
      try {
        checkJobAccess( id, PentahoSessionHolder.getSession() );
        IScheduler scheduler = getScheduler();
        scheduler.removeJob( id );
      } catch ( Exception e ) {
        return getError( e );
      }
      return new JsonGeneratorSerializable() {
  
        public void writeToGenerator( JsonGenerator out ) throws IOException {
          out.writeStartObject();
          out.writeStringField( STATUS_FIELD, STATUS_OK );
          out.writeEndObject();
        }
      };
    }
  
    public JsonGeneratorSerializable executeJob( String id ) {
      IScheduler scheduler = getScheduler();
      try {
        checkJobAccess( id, PentahoSessionHolder.getSession() );
        scheduler.triggerNow( id );
      } catch ( Exception e ) {
        return getError( e );
      }
      return new JsonGeneratorSerializable() {
  
        public void writeToGenerator( JsonGenerator out ) throws IOException {
          out.writeStartObject();
          out.writeStringField( STATUS_FIELD, STATUS_OK );
          out.writeEndObject();
        }
      };
    }
  
    /**
     * CacheController#list
     *
     * @return
     */
    public JsonGeneratorSerializable listScheduledQueries() {
      IScheduler scheduler = getScheduler();
      try {
        List<Job> jobs = scheduler.getJobs( getCdaJobFilter() );
        final List<JsonGeneratorSerializable> queries = new ArrayList<>();
        for ( Job job : jobs ) {
          addJobInfoToScheduledQueries( queries, job );
        }
  
        return new JsonGeneratorSerializable() {
          public void writeToGenerator( JsonGenerator out ) throws IOException {
            out.writeStartObject();
            out.writeStringField( STATUS_FIELD, STATUS_OK );
            out.writeFieldName( "queries" );
            out.writeStartArray();
            for ( JsonGeneratorSerializable query : queries ) {
              query.writeToGenerator( out );
            }
            out.writeEndArray();
            out.writeEndObject();
          }
        };
      } catch ( SchedulerException e ) {
        getLog().error( " Error fetching job list.", e );
      }
      return null;
    }
  
    private void addJobInfoToScheduledQueries( List<JsonGeneratorSerializable> queries, Job job ) {
      try {
        String jsonString = (String) job.getJobParams().get( CdaCacheWarmer.QUERY_INFO_PARAM );
        queries.add( toCachedQueryJson( new ScheduledQueryExecution( getSettingsManager(), jsonString, job ) ) );
      } catch ( Exception e ) {
        getLog().error( "Error reading job info.", e );
      }
    }
  
    private SettingsManager getSettingsManager() {
      return CdaEngine.getInstance().getSettingsManager();
    }
  
    private IJobFilter getCdaJobFilter() {
      return job -> job.getJobName().startsWith( JOB_NAME_PREFIX )
        && job.getJobParams().containsKey( CdaCacheWarmer.QUERY_INFO_PARAM )
        // avoid listing temporary one-shot jobs from execute
        && job.getNextRun() != null && job.getNextRun().getTime() > 0;
    }
  
    private void checkSchedulerAccess( QueryExecution queryExec, IPentahoSession session ) throws AccessDeniedException {
      if ( !canSchedule( ) ) {
        throw new AccessDeniedException(
          String.format( "User %s cannot schedule %s",
            session.getName(),
            queryExec.getCdaSettings().getId() ), null
        );
      }
    }
  
    private void checkJobAccess( String jobId, IPentahoSession session )
      throws AccessDeniedException, SchedulerException {
      IScheduler scheduler = getScheduler();
      Job job = scheduler.getJob( jobId );
      if ( job == null ) {
        throw new IllegalArgumentException( "No such job." );
      }
      if ( !session.getName().equals( job.getUserName() ) && !PentahoHelper.isAdmin( session ) ) {
        throw new AccessDeniedException( "User must be admin or be the job owner to access existing job ", null );
      }
    }
  
    private boolean canSchedule( ) {
      // access rights to cda already checked by SettingsManager
      IAuthorizationPolicy authPolicy = getAuthorizationPolicy();
      if ( authPolicy == null ) {
        getLog()
          .error( String.format( "Unable to get authorization policy (%s)", IAuthorizationPolicy.class.getName() ) );
        return false;
      }
      // we can also check for scheduling permissions for this particular file
      // just scheduling permissions and cda access should be enough
      return authPolicy.isAllowed( SchedulerAction.NAME );
    }
  
    private IAuthorizationPolicy getAuthorizationPolicy() {
  