SaveIntoDatabase: Can’t create handler inside thread that has not called Looper.prepare()

Tengo un porblema a la hora de cargar mi base de datos SQlite con un array en segundo plano, el problema es el siguiente:

 SaveIntoDatabase: Can't create handler inside thread that has not  called Looper.prepare() 

Estuve investigando sobre looper para entender su funcionamiento, intente llamar a Looper.prepare dentro del void run(), pero no hubo diferencia

Aqui el codigo

public class ProductFetcher extends Thread {      private final ProductFetchListener mListener;     private final SQLiteDatabase mDb;      public ProductFetcher(ProductFetchListener listener, SQLiteDatabase db) {         mListener = listener;         mDb = db;     }      @Override     public void run() {          Cursor cursor = mDb.rawQuery(Constants.DATABASE.GET_PRODUCTS_QUERY, null);          final List<Product> productList = new ArrayList<>();          if (cursor.getCount() > 0) {              if (cursor.moveToFirst()) {                 do {                     Product product = new Product();                     product.setFromDatabase(true);                     Aqui cargo los campos del producto                        productList.add(product);                     publishProduct(product);                  } while (cursor.moveToNext());             }         }         Handler handler = new Handler(Looper.getMainLooper());          handler.post(new Runnable() {             @Override             public void run() {                  mListener.onDeliverAllProducts(productList);                 mListener.onHideDialog();             }         });     }      public void publishProduct(final Product product) {         Handler handler = new Handler(Looper.getMainLooper());         handler.post(new Runnable() {             @Override             public void run() {                 mListener.onDeliverProduct(product);             }         });     } } 

Intente tambien colocar el Looper.prepare() dentro de todos los public void run(), y el resultado era que no podia llamar a mas de uno por thread

Update Handler is not getting called

I am following the exact same logic as CatalogRule. Everything is working properly. All data are saving in my vendor_rule table but website ids are not saving in my vendor_rule_website.

I do have ReadHandler and SaveHandler in place but SaveHandler is not getting called. When I manually add data to vendor_rule_website then it actually reads the website table. I have also confirmed that ReadHandler class is being called.

My di.xml file has this:

  <type name="Magento\Framework\EntityManager\MetadataPool">     <arguments>         <argument name="metadata" xsi:type="array">             <item name="Vendor\NameSpace\Api\Data\RuleInterface" xsi:type="array">                 <item name="entityTableName" xsi:type="string">vendor_rule</item>                 <item name="identifierField" xsi:type="string">rule_id</item>             </item>         </argument>     </arguments> </type>       <type name="Magento\Framework\EntityManager\Operation\AttributePool">         <arguments>             <argument name="extensionActions" xsi:type="array">                 <item name="digitalShipping" xsi:type="array">                     <item name="Vendor\NameSpace\Api\Data\RuleInterface" xsi:type="array">                         <item name="read" xsi:type="string">Vendor\NameSpace\Model\ResourceModel\ReadHandler</item>                         <item name="create" xsi:type="string">Vendor\NameSpace\Model\ResourceModel\SaveHandler</item>                         <item name="update" xsi:type="string">Vendor\NameSpace\Model\ResourceModel\SaveHandler</item>                     </item>                 </item>             </argument>         </arguments>     </type>      <type name="Magento\Framework\EntityManager\HydratorPool">         <arguments>             <argument name="hydrators" xsi:type="array">                 <item name="Vendor\NameSpace\Api\Data\RuleInterface" xsi:type="string">Magento\Framework\EntityManager\AbstractModelHydrator</item>         </arguments>     </type> 

My SaveHandler.php:

namespace Vendor\NameSpace\Model\ResourceModel;  use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\EntityManager\Operation\AttributeInterface;  /**  * Class SaveHandler  */ class SaveHandler implements AttributeInterface {     /**      * @var Rule      */     protected $  ruleResource;      /**      * @var MetadataPool      */     protected $  metadataPool;      /**      * @param Rule $  ruleResource      * @param MetadataPool $  metadataPool      */     public function __construct(         \Vendor\NameSpace\Model\ResourceModel\Rule $  ruleResource,         MetadataPool $  metadataPool     ) {         $  this->logMe("save handler construct");         $  this->ruleResource = $  ruleResource;         $  this->metadataPool = $  metadataPool;     }      /**      * @param string $  entityType      * @param array $  entityData      * @param array $  arguments      * @return array      * @throws \Exception      */     public function execute($  entityType, $  entityData, $  arguments = [])     {         $  linkField = $  this->metadataPool->getMetadata($  entityType)->getLinkField();         if (isset($  entityData['website_ids'])) {             $  websiteIds = $  entityData['website_ids'];             if (!is_array($  websiteIds)) {                 $  websiteIds = explode(',', (string)$  websiteIds);             }             $  this->ruleResource->bindRuleToEntity($  entityData[$  linkField], $  websiteIds, 'website');         }          if (isset($  entityData['customer_group_ids'])) {             $  customerGroupIds = $  entityData['customer_group_ids'];             if (!is_array($  customerGroupIds)) {                 $  customerGroupIds = explode(',', (string)$  customerGroupIds);             }             $  this->ruleResource->bindRuleToEntity($  entityData[$  linkField], $  customerGroupIds, 'customer_group');         }         return $  entityData;     } 

Why is not my SaveHandler class getting called? Is there another way to save associated tables?

mmap handler is not running when mmap function is called

I have recently added a mmap handler in my device driver. Open call and close call are working fine. But when i perform mmap system call, it doesn’t run at all.Can somebody help me with this.

mmap Handler:

int mmmap(struct file *fptr, struct vm_area_struct *vma) {         scull *s;         printk(KERN_INFO "Begin : %s\n",__func__);          s=fptr->private_data;          if(remap_pfn_range(vma,vma->vm_start,virt_to_pfn(s->buffer),(vma->vm_end - vma->vm_start),vma->vm_page_prot) == -1)         {                 printk(KERN_INFO "remap_pfn_range failed \n");                 return -EAGAIN;         }          printk(KERN_INFO "End : %s\n",__func__);         return 0; } 

Application:

#include<stdio.h> #include<stdlib.h> #include<fcntl.h> #include<unistd.h> #include<sys/mman.h> int main(void) {         int fd;         void *ptr;          ptr=NULL;          printf("pid : %d\n",getpid());         fd=open("../mydev",O_RDONLY);         if(fd == -1)         {                 perror("file did not open \n");                 exit(EXIT_FAILURE);          }        ptr=mmap(ptr,sizeof(char)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);        if(!ptr)        {                 perror("mmap");                 exit(EXIT_FAILURE);        }          printf("mmap worked \n");         munmap(ptr,sizeof(char)*10);          close(fd);         return 0; }         

Почему создается новый Handler?

Почему во втором классе мы создаем два Handler mResponseHandler и mRequestHandler. Почему нужно создать mResponseHandler в onCreate и затем передать в контруктор mThumbnailDownloader. Т.е почему в методе hanldeRequest мы вызывает Runnablе и там уже вызываем метод слушателя. Почему это нельзя сделать в mRequestHandler ?

Есть такой код:

public class PhotoGalleryFragment extends Fragment{  private static final String TAG = "PhotoGalleryFragment"; private RecyclerView mRecyclerView; private List<GalleryItem> mItems = new ArrayList<>(); private ThumbnailDownloader<PhotoHolder> mThumbnailDownloader;  public static PhotoGalleryFragment newInstance(){     return new PhotoGalleryFragment(); }  @Override public void onCreate(@Nullable Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setRetainInstance(true);     new FetchItemsTask().execute();      Handler responseHandler = new Handler();      mThumbnailDownloader = new ThumbnailDownloader<>(responseHandler);     mThumbnailDownloader.setThumbnailDownloadListener(new ThumbnailDownloader.ThumbnailDownloadListener<PhotoHolder>() {         @Override         public void onThumbnailDownloaded(PhotoHolder target, Bitmap thumbnail) {             Drawable drawable = new BitmapDrawable(getResources(), thumbnail);             target.bindDrawable(drawable);         }     });     mThumbnailDownloader.start();     mThumbnailDownloader.getLooper();     Log.i(TAG, "Background thread started"); } 

и есть второй класс:

public class ThumbnailDownloader<T> extends HandlerThread {  private static final String TAG = "ThumbnailDownloader"; private static final int MESSAGE_DOWNLOAD = 0;  private Handler mRequestHandler; private Handler mResponseHandler; private ConcurrentMap<T, String> mRequestMap = new ConcurrentHashMap<>(); private boolean mHasQuit = false; private ThumbnailDownloadListener<T> mThumbnailDownloadListener; public interface ThumbnailDownloadListener<T>{     void onThumbnailDownloaded(T target, Bitmap thumbnail); }  public void setThumbnailDownloadListener(ThumbnailDownloadListener<T> listener){     mThumbnailDownloadListener = listener; }  public ThumbnailDownloader(Handler responseHandler) {     super(TAG);     mResponseHandler = responseHandler; } @Override protected void onLooperPrepared() {     mRequestHandler = new Handler(){         @Override         public void handleMessage(@NonNull Message msg) {             if(msg.what == MESSAGE_DOWNLOAD){                 T target = (T)msg.obj;                 Log.i(TAG, "Got a request for url " + mRequestMap.get(target));                 handleRequest(target);             }         }     }; }    private void handleRequest(final T target){     try {         final String url = mRequestMap.get(target);         if (url == null) {             return;         }          byte[] bitmapBytes = new FlickrFetchr().getUrlBytes(url);         final Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);         Log.i(TAG, "Bitmap created");          mResponseHandler.post(new Runnable() {             @Override             public void run() {                 if(mRequestMap.get(target) != url || mHasQuit){                     return;                 }                  mRequestMap.remove(target);                 mThumbnailDownloadListener.onThumbnailDownloaded(target, bitmap);             }         });     }catch (IOException e){         Log.i(TAG, "Error downloading image");     } } 

¿Como mostrar un mensaje o alerta en la pagina web desde un Generic Handler?

Hola comunidad espero me puedan ayudar y decirme que estoy haciendo mal o si esto es posible ya que aun no logro mostrar lo que necesito de antemano gracias.

Estoy subiendo un archivo al servidor pero no quiero que realice el postback así que utilizo un fileupload de html un GenericHandler y ajax. La extension ya la valide en el control del fileupload la propiedad accept pero también quiero validar en el generic handler y si la extension no es correcta mostrar un mensaje en una label o una alerta en mi formulario web desde el Generic Handler.

Bueno mi pregunta es: ¿Como mostrar ese mensaje desde el generic handler?

Aqui coloco mi codigo ajax

  $  (".custom-file-input").on("change", function() {             var fileName = $  (this).val().split("\").pop();             $  (this).siblings(".custom-file-label").addClass("selected").html(fileName);              if (fileupload.value != '') {                  $  .ajax({                     url: '/script/GuardarExcel.ashx',                     type: 'POST',                     data: new FormData($  ('form')[0]),                     cache: false,                     contentType: false,                     processData: false,                     success: function() {                                            },                     error: function() {                                           }                 });               }           });
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>   <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>  <label id="lblArchivo" class=" labelColor btn btn-primary" style="background-color:#5AAAFF; border-color:#5AAAFF" for="fileupload">seleccione archivo                     <input id="fileupload" type="file" name="fileupload" class="custom-file-input" accept=".xlsx"  />                     </label>

Aquí coloco el código de mi generic handler

 public void ProcessRequest(HttpContext context)     {          if (context.Request.Files.Count > 0)         {             //Fetch the Uploaded File.             HttpPostedFile postedFile = context.Request.Files[0];                string fileName = Path.GetFileName(postedFile.FileName);             string fileExtension = Path.GetExtension(postedFile.FileName).ToLower();              if (fileExtension == ".xlsx") // Compruebo que la extension sea la correcta             {                  string folderPath = context.Server.MapPath("~/Excel_Archivos/" + fileName);                 context.Session["folderPath"] = folderPath;                   postedFile.SaveAs(folderPath);               }             else // Aqui quiero mostrar el mensaje en caso de que la extension no sea la correcta pero no logro mostrar nada.             {                  StringBuilder sb = new StringBuilder();                 sb.Append("<body>");                 sb.Append("Error de archivo");                                     sb.Append("</body>");                  context.Response.ContentType = "text/html";               }          }     }      public bool IsReusable     {         get         {             return false;         }     } 

PHP Error handler class

I set up an error handler class to handle all server errors, I know there are already quite a few out there, but I like creating my own for better learning and understanding of how things work. I am currently using this in a framework I am working on (again, for learning purposes), and its working as it should.

With this error handler you can:

  1. Choose if to log the error
  2. Choose the file to log it to
  3. Send the error to an email if enabled
  4. Add a custom error page
  5. Set a custom general error message if no error page is set

The way it works and is set up is like this:

  1. You set up your app settings:
 /* App settings ===============================================*/  //App name define("APP_NAME", "Test App");  //App url define("APP_URL", "https://testapp.com");  //Support email define("APP_SUPPORT_EMAIL", "support@testapp.com");    /* Error handling settings (used in ErrorHandler.php) ===============================================*/  //Set debug mode define("DEBUG_MODE", true);  //Log errors define("LOG_ERRORS", true);  //Send error reports to email define("SEND_ERROR_EMAILS", true);  //Email to send the error reports to define("ERROR_REPORTING_EMAIL", "security@testapp.com");  //Path to the error log file define("ERROR_LOG_PATH", $  _SERVER['DOCUMENT_ROOT']."/../logs/error_log.log");  //Path to the "500" error page define("ERROR_PAGE_PATH", $  _SERVER['DOCUMENT_ROOT']."/../framework/defaults/pages/error500.php");  //Default error message (if no error page is set or found) define("PUBLIC_ERROR_MESSAGE", "Looks like there was an error. We are already looking in to it!"); 

Then you either load the error handler with an auto loader, or load it directly (how ever the developer chooses to do it), and then you set the error handler to be the default one with: set_error_handler(array(new ErrorHandler(), 'handleError'));

And for the actual error handler class:

<?  class ErrorHandler{      //Set default class properties     private $  debugMode          = false;     private $  logErrors          = false;     private $  sendEmail          = false;     private $  securityEmail      = null;     private $  publicErrorMessage = "Looks like there was an error. We are already looking in to it!";     private $  appName            = null;     private $  appSupportEmail    = null;       /* Constructor - Sets up the class settings     ===========================================*/     public function __construct(){          //Update class properties from defined constants if they are set         $  this->debugMode            = (defined('DEBUG_MODE')?DEBUG_MODE:$  this->debugMode);         $  this->logErrors            = (defined('LOG_ERRORS')?LOG_ERRORS:$  this->logErrors);         $  this->sendEmail            = (defined('SEND_ERROR_EMAILS')?SEND_ERROR_EMAILS:$  this->sendEmail);         $  this->securityEmail        = (defined('ERROR_REPORTING_EMAIL')&&filter_var(ERROR_REPORTING_EMAIL, FILTER_VALIDATE_EMAIL)?ERROR_REPORTING_EMAIL:$  this->securityEmail);         $  this->publicErrorMessage   = (defined('PUBLIC_ERROR_MESSAGE')?PUBLIC_ERROR_MESSAGE:$  this->publicErrorMessage);         $  this->appName              = (defined('APP_NAME')?APP_NAME:$  this->appName);         $  this->appSupportEmail      = (defined('APP_SUPPORT_EMAIL')&&filter_var(APP_SUPPORT_EMAIL, FILTER_VALIDATE_EMAIL)?APP_SUPPORT_EMAIL:$  this->appSupportEmail);           //Create new class properties from defined constants if they are set         $  this->errorLogPath         = (defined('ERROR_LOG_PATH')?ERROR_LOG_PATH:$  _SERVER['DOCUMENT_ROOT']."/../logs/error_log.log");         $  this->errorPagePath        = (defined('ERROR_PAGE_PATH')?ERROR_PAGE_PATH:$  _SERVER['DOCUMENT_ROOT']."/../framework/defaults/pages/error500.php");     }        /*  Handle error     ===========================================*/     public function handleError($  errno, $  errstr, $  errfile=false, $  errline=false){          //Save the error data         $  this->errno    = $  errno;         $  this->errstr   = $  errstr;         $  this->errfile  = $  errfile;         $  this->errline  = $  errline;           //If logging errors is enabled         if($  this->logErrors){             $  this->saveToLog();         }           //If email reporting is enabled         if($  this->sendEmail && $  this->securityEmail){             $  this->sendToEmail();         }           //Load the error page         $  this->loadErrorPage();     }        /* Save the error to a log     ===========================================*/     private function saveToLog(){          //Get the error string         $  errorString = $  this->getErrorString();           //Save the error to the log         error_log($  errorString,3,$  this->errorLogPath);     }        /* Send the error to the set email     ===========================================*/     private function sendToEmail(){          //Get the error string         $  errorString = $  this->getErrorString(true);           //Set the email headers         $  headers = "MIME-Version: 1.0" . "\r\n";         $  headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";         $  headers .= "From: ".$  this->appName." Security <".$  this->securityEmail.">\r\n";         $  headers .= "Reply-To: ".$  this->securityEmail."" . "\r\n";           //Send the email         @mail($  this->securityEmail, "An error has occured", $  errorString, $  headers);     }        /* Load the error page     ===========================================*/     private function loadErrorPage(){          //If there is no error page path or the file doesnt exist, output a message         if(!$  this->errorPagePath || !file_exists($  this->errorPagePath)){              //Output a general error message             echo $  this->publicErrorMessage;               //If debug mode is enabled, output the error             if($  this->debugMode){                 echo "<BR><BR>";                 echo $  this->getErrorString(true);             }             exit();           /*  If there is an error page path and it exists, include it         *   The file itself has access to the error string, it will         *   output it if debug mode is enabled.          *   Custom error files can be used by definining the constant ERROR_PAGE_PATH */         }else{             include($  this->errorPagePath);             exit();         }     }        /*  Set up the error string to be logged or emailed     *   Receives an argument for the type of output.     *   Lines are separated by \n or <BR> (based on the $  output argument).     ===========================================*/     private function getErrorString($  output = false){          //Switch between the error numbers and set up the error type variable         switch ($  this->errno) {             case E_NOTICE:             case E_USER_NOTICE:             case E_DEPRECATED:             case E_USER_DEPRECATED:             case E_STRICT:                 $  errorType = "NOTICE";                 break;              case E_WARNING:             case E_USER_WARNING:                 $  errorType = "WARNING";                 break;              case E_ERROR:             case E_USER_ERROR:             case E_RECOVERABLE_ERROR:                 $  errorType = "FATAL";              default:                 $  errorType = "UNKNOWN";         }           //Set up the separator based on the $  output argument         if($  output){             $  separator = "<BR>";         }else{             $  separator = "\n";         }           //Set up the error string         $  errorString = $  errorType.' ['.$  this->errno.'] At: '.date("j M y - g:i:s A (T)", time()).":".$  separator."";         $  errorString .= "File: ".$  this->errfile." (Line: ".$  this->errline.")".$  separator."";         $  errorString .= "Message: ".$  this->errstr."".$  separator."";         $  errorString .= "Backtrace: ".$  this->backTraceError()."".$  separator."";         $  errorString .= "------------------------------------------".$  separator."";           //Return the error string         return $  errorString;     }        /* Function to back trace the error     ===========================================*/     private function backTraceError(){          //Set up backtrace vairables         $  rawBacktrace = debug_backtrace();         $  cleanBacktrace = $  backtraceSeparator = '';         $  i = 0;           //Loop through the backtrace         foreach($  rawBacktrace as $  a_key => $  a_value){              /*  Skip the first two iterations             *   The first two are inside this file itself, we             *   want to see the backtrace until the error. */             if($  i < 3){                 $  i++;                 continue;             }               //If the counter is over 2, add a separator             if($  i > 3){                 $  backtraceSeparator = ' < ';             }               //If a file and line are set             if(isset($  a_value['file']) && isset($  a_value['line'])){                 $  cleanBacktrace .= $  backtraceSeparator.basename($  a_value['file']).' ['.$  a_value['line'].']';             }               //Increment the counter             $  i++;         }           //Return the backtrace         return $  cleanBacktrace;     } } 

The output of the error is like this:

WARNING [2] At: 20 Jun 19 - 4:28:02 PM (UTC): File: /home/framework/core/Application.php (Line: 9) Message: Use of undefined constant s - assumed 's' (this will throw an Error in a future version of PHP) Backtrace: ErrorHandler.php [49] < Application.php [9] < index.php [17] ------------------------------------------ 

I tried to make it as customization as I could. Since this is part of the framework I am working on, it comes with a default error500.php file, but if there isn’t one then a general message will be shown. Developers also have the option to use their own error pages. The error pages have access to the properties of the error handler class since they are included in it, so the error and other data can be shown for debugging.

Any feedback on this would be great!

Apply generateOptions() to Custom query() in Views Filter Handler

I am trying to understand how I get the options from generateOptions() to apply to my query() function in a ManyToOne Class.

class MyClass extends ManyToOne {    public function init(ViewExecutable $  view, DisplayPluginBase $  display, array &$  options = NULL) {     parent::init($  view, $  display, $  options);     $  this->definition['options callback'] = [$  this, 'generateOptions'];   }    public function query() {      $  currentUserID = \Drupal::currentUser()->id();      $  configuration = [       'table' => 'node_access',       'field' => 'nid',       'left_table' => 'node_field_data',       'left_field' => 'nid',       'operator' => '=',     ];      $  join = Views::pluginManager('join')       ->createInstance('standard', $  configuration);      $  this->query       ->addRelationship('node_access', $  join, 'node_field_data');      $  this->query       ->addWhere('AND', 'node_access.gid', $  currentUserID, '=');      // Need another "addWhere()" statement based on options below. Something like:     $  this->query       ->addWhere('AND', 'node_access.' . array_values($  this->value), '1', $  this->operator); // <- Unsure.    }    public function generateOptions() {      return [       'grant_view' => 'Grant View',       'grant_update' => 'Grant Update',       'grant_delete' => 'Grant Delete',     ];   }  } 

Can’t say my approach is perfect!

Fundamentals: I am unsure if I use helper functions to filter my query() return, or if I get/apply options inside the query() itself.

I have tried to find the options in the query array without success.

How would I apply the generateOptions() to my query()?

If this question is best answered with a better question, I would be happy. Trying to get this to click.

Drupal 8 : Multiple Submit Handler

I am using Drupal 8.6 for creating custom module in Admin. I have a custom form where i have to use multiple submit button for form submission. I am not able to submit the my form to specific function. Below is my code.

public function buildForm(array $ form, FormStateInterface $ form_state) {

$  connection = \Drupal::service('database');      $  form_state->setMethod('get');      $  build = [];       /* $  build['form'] = [     '#type'  => 'get', ]; */  $  build['submit_button_1'] = [           '#type' => 'submit',            '#value' => t('Download CSV'),           '#name' => t('downloadcsv'),           '#executes_submit_callback'=>FALSE,                        '#submit' => array('::downloadcsv'),      ];   $  build['form']['filters'] = [     '#type'  => 'fieldset',     '#title' => $  this->t('Filter'),     '#open'  => true, ];   $  build['form']['filters']['autocomplete_field'] = array( '#type' => 'textfield', '#title'         => 'Search by Name', '#autocomplete_route_name' => 'form_request.autocomplete', '#autocomplete_route_parameters' => array('field_name' => 'name', 'count' => 10), '#default_value' => isset($  _GET['autocomplete_field']) ? trim($  _GET['autocomplete_field']):'', 

);

$  build['form']['filters']['form_name'] = [     '#title'         => 'Form Name',     '#type'          => 'select',     '#empty_value'   => 'none',     '#empty_option'  => '- None -',     '#size'          => 0,     '#options'       => $  this->get_formlist(),     '#default_value' => isset($  _GET['form_name']) ? trim($  _GET['form_name']):'' ];  $  build['form']['filters']['request_status'] = [     '#title'         => 'Request Status',     '#type'          => 'select',     '#empty_value'   => 'all',     '#empty_option'  => '- None -',     '#size'          => 0,     '#options'       => array("all"=>"All","inprogress"=>"In progress","pending"=>"Pending","completed"=>"Completed",'rejected' => "Rejected"),     '#default_value' => isset($  _GET['request_status']) ? trim($  _GET['request_status']):'' ];   $  build['form']['filters']['actions']['submit'] = [     '#type'  => 'submit',     '#value' => $  this->t('Filter') ];   $  build['form']['filters']['actions']['reset'] = [     '#type'  => 'button',     '#value' => $  this->t('Reset'),     '#target'=>'_self',     '#attributes' => array(         'onclick' => 'redirectURL("'.$  resetURL.'")',         //'onclick' => '$  ("#form-request").reset()',       ), ]; 

return $ build;

}

public function downloadcsv(array &$ form, FormStateInterface $ form_state) {

 echo "aaaaa"; exit; 

}

Не понимаю как создать ссылку на следующий handler, которые лежать в списке handlers

У меня учебный проект на Spring MVC и я пытаюсь применить паттерн Chain of responsibility. Создал пакет handler в котором есть интерфейс Handler

public interface Handler {     void setRelationship(Relationship relationship, User user, String status, Long userIdTo, Long idUserFrom)throws BadRequestException, InternalServerError; } 

Абстрактный класс

public abstract class RelationshipHandler implements Handler, Ordered {      public abstract void setRelationship(Relationship relationship, User user, String status, Long userIdTo, Long idUserFrom)throws BadRequestException, InternalServerError;      boolean checkStatusForChange(Relationship relationship, RelationshipStatusType currentStatus, RelationshipStatusType newStatus, String status){         return relationship != null && relationship.getStatusType().equals(currentStatus) && status.equals(newStatus.toString());     } } 

От которого наследуются четыре обработчика Первый

@Component public class AcceptedHandler extends RelationshipHandler {      private final RelationshipDAO relationshipDAO;      @Autowired     public AcceptedHandler(RelationshipDAO relationshipDAO) {         this.relationshipDAO = relationshipDAO;     }      @Override     public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError{         if (user != null && user.getId().equals(idUserTo) &&                 checkStatusForChange(relationship, RelationshipStatusType.REQUESTED, RelationshipStatusType.ACCEPTED, status)){             relationshipDAO.update(addFriendsByRequest(user, relationship));         }     }      private Relationship addFriendsByRequest(User user, Relationship relationship) throws BadRequestException, InternalServerError {         if (user == null || relationship == null){             throw new BadRequestException("User or relationship is not found.");         }          if (checkingNumberFriends(user.getId())){             Date acceptedRequest = new Date();             relationship.setAcceptedFriends(acceptedRequest);             relationship.setStatusType(RelationshipStatusType.ACCEPTED);         }         else {             throw new BadRequestException("Friends limit exceeded.");         }         return relationship;     }      private boolean checkingNumberFriends(Long id) throws BadRequestException, InternalServerError {          if (id == null){             throw new BadRequestException("ID does not exist.");         }         return relationshipDAO.getQuantityFriends(id, RelationshipStatusType.ACCEPTED) < 10;     }      @Override     public int getOrder() {         return Ordered.HIGHEST_PRECEDENCE;     } } 

Второй

@Component public class DeletedHandler extends RelationshipHandler {      private final RelationshipDAO relationshipDAO;      @Autowired     public DeletedHandler(RelationshipDAO relationshipDAO) {         this.relationshipDAO = relationshipDAO;     }      @Override     public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError {         if (user != null && (user.getId().equals(idUserFrom) || user.getId().equals(idUserTo)) &&                 checkStatusForChange(relationship, RelationshipStatusType.ACCEPTED, RelationshipStatusType.DELETED, status)){             relationshipDAO.update(delFromFriends(idUserFrom, idUserTo,  relationship));         }     }      private Relationship delFromFriends(Long idUserFrom, Long idUserTo, Relationship relationship) throws BadRequestException, InternalServerError {         if (idUserFrom == null || idUserTo == null || relationship == null){             throw new BadRequestException("IdUserFrom or idUserTo or relationship is not found.");         }          if (checkingAcceptedDate(idUserFrom, idUserTo)){             relationship.setStatusType(RelationshipStatusType.DELETED);             relationship.setAcceptedFriends(null);         }         else {             throw new BadRequestException("You can not perform an action delete from friends.");         }         return relationship;     }      private boolean checkingAcceptedDate(Long idUserFrom, Long idUserTo) throws BadRequestException, InternalServerError{         if (idUserFrom == null || idUserTo == null){             throw new BadRequestException("IdUserFrom or idUserTo is not found.");         }         return relationshipDAO.getQuantityHoursAfterAccepted(idUserFrom, idUserTo, RelationshipStatusType.ACCEPTED) >= 3;     }      @Override     public int getOrder() {         return 2;     } } 

Третий

@Component public class CanceledHandler extends RelationshipHandler {      private final RelationshipDAO relationshipDAO;      @Autowired     public CanceledHandler(RelationshipDAO relationshipDAO) {         this.relationshipDAO = relationshipDAO;     }      @Override     public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError {         if (user != null && user.getId().equals(idUserFrom) &&                 checkStatusForChange(relationship, RelationshipStatusType.REQUESTED, RelationshipStatusType.CANCELED, status)){             relationship.setStatusType(RelationshipStatusType.CANCELED);             relationshipDAO.update(relationship);         }     }      @Override     public int getOrder() {         return 3;     } } 

И четвертый

@Component public class DeclinedHandler extends RelationshipHandler {      private final RelationshipDAO relationshipDAO;      @Autowired     public DeclinedHandler(RelationshipDAO relationshipDAO) {         this.relationshipDAO = relationshipDAO;     }      @Override     public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError {         if (user != null && user.getId().equals(idUserTo) &&                 checkStatusForChange(relationship, RelationshipStatusType.REQUESTED, RelationshipStatusType.DECLINED, status)) {             relationship.setStatusType(RelationshipStatusType.DECLINED);             relationshipDAO.update(relationship);         }     }      @Override     public int getOrder() {         return 1;     } } 

Класс в котором строю цепочку

@Component public class HandlerForUser {      @Autowired     private List<Handler> handlers;      @PostConstruct     public void init(){         handlers.sort(INSTANCE);     }      public void execute(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom)throws BadRequestException, InternalServerError {         for (Handler handler : handlers){             handler.setRelationship(relationship, user, status, idUserTo, idUserFrom);         }     } } 

И использую это в сервисе:

@Service public class RelationshipService {      private RelationshipDAO relationshipDAO;     private UserDAO userDAO;     private HandlerForUser handlerForUser;      @Autowired     public RelationshipService(RelationshipDAO relationshipDAO, UserDAO userDAO, HandlerForUser handlerForUser) {         this.relationshipDAO = relationshipDAO;         this.userDAO = userDAO;         this.handlerForUser = handlerForUser;     }      public void setRelationship(String userIdTo, String userIdFrom, HttpSession session)throws BadRequestException, InternalServerError{         User userFrom = (User) session.getAttribute(userIdFrom);         if (userFrom == null){             throw new BadRequestException("User with ID " + userIdFrom + " is not logged in.");         }          User userTo = userDAO.findById(Long.parseLong(userIdTo));         if (userTo == null){             throw new BadRequestException("User with ID " + userIdTo + " is not found in DB.");         }          Relationship relationshipFind = relationshipDAO.getRelationship(userFrom.getId(), userTo.getId());         try {             if (relationshipFind == null){                 Relationship relationship = new Relationship();                 relationship.setUserFrom(userFrom);                 relationship.setUserTo(userTo);                 relationship.setStatusType(RelationshipStatusType.REQUESTED);                 save(sendRequest(Long.parseLong(userIdFrom), relationship));             }             else if (relationshipFind.getStatusType().equals(RelationshipStatusType.CANCELED) ||                     relationshipFind.getStatusType().equals(RelationshipStatusType.DECLINED) ||                     relationshipFind.getStatusType().equals(RelationshipStatusType.DELETED)){                 relationshipFind.setStatusType(RelationshipStatusType.REQUESTED);                 relationshipDAO.update(sendRequest(Long.valueOf(userIdFrom), relationshipFind));             }             else {                 throw new BadRequestException("Something is wrong with the input.");             }         }catch (InternalServerError e) {             throw new InternalServerError("Something went wrong...");         }     }      public void setRelationshipByStatus(String status, String userIdTo, String userIdFrom, HttpSession session) throws BadRequestException, InternalServerError {         if (status == null || userIdTo == null || userIdFrom == null){             throw  new BadRequestException("Status or userIdTo or userIdFrom is not exist.");         }          User userFrom = (User) session.getAttribute(userIdFrom);         User userTo = (User) session.getAttribute(userIdTo);         Relationship relationshipFind = relationshipDAO.getRelationship(Long.valueOf(userIdFrom), Long.valueOf(userIdTo));          try {             if (userTo != null){                 handlerForUser.execute(relationshipFind, userTo, status, Long.valueOf(userIdTo), Long.valueOf(userIdFrom));             }              if (userFrom != null){                 handlerForUser.execute(relationshipFind, userFrom, status, Long.valueOf(userIdTo), Long.valueOf(userIdFrom));             }             else {                 throw new BadRequestException("Something is wrong with the input. Method setRelationshipByStatus");             }         }catch (InternalServerError e) {             throw new InternalServerError("Something went wrong...");         }     }      public void validationInputData(String idUserFrom, String idUserTo, HttpSession session)throws BadRequestException{         if (idUserFrom == null || idUserTo == null){             throw  new BadRequestException("UserFrom or userTo does not exist.");         }          if (idUserFrom.equals(idUserTo)){             throw  new BadRequestException("Actions between the same user are not possible.");         }          if (session == null){             throw  new BadRequestException("Session is not exist.");         }     }      private Relationship save(Relationship relationship)throws BadRequestException {         if (relationship != null && relationship.getId() != null){             throw new BadRequestException("This Relationship with ID - " + relationship.getId() + " can not save in DB.");         }         else {             relationshipDAO.save(relationship);         }         return relationship;     }      private Relationship sendRequest(Long idUser, Relationship relationship) throws BadRequestException, InternalServerError {         if (idUser == null || relationship == null){             throw new BadRequestException("User or relationship is not found.");         }          if (checkingNumberRequested(idUser)){             relationship.setStatusType(RelationshipStatusType.REQUESTED);         }         else {             throw new BadRequestException("Limit on sent requests exceeded.");         }         return relationship;     }      private boolean checkingNumberRequested(Long id) throws BadRequestException, InternalServerError{         if (id == null){             throw new BadRequestException("ID does not exist.");         }         return relationshipDAO.getQuantityRequests(id, RelationshipStatusType.REQUESTED) < 10;     } } 

Сейчас получается, что запрос проходит по всему списку обработчиков не прерывая цепочку если запрос обработался успешно. Может я структуру построил не правильно. Наверное в абстрактном классе надо задать поведение для передачи ссылки на следующий обработчик. Что-то ни как не соображу, что делать дальше… Помогите разобраться, как правильно построить цепочку

List link to library xml file opens in browser instead of Office XML handler

I have a bunch of documents that are either word or excel files generated by a third party program. They are all saved with an XML file extension. When opening the file from File explorer, office xml handler determines which office prg to open them with and does so. I have uploaded all these XML files to a Sharepoint library. When click on the name of the file in the library they open in the appropriate program. I next created a list based on an excel index file that is provided. In this list I created a link to the file in the sharepoint file when there is an appropriate list entry. The problem is when using the link, the xml file is opened up in the web browser and is all the “Raw” formatting of the xml file.

I did some research and found the opposite problem where people were trying to force the links to open in OWA (assuming that is Office Web Application) in the browser instead of downloading the file. The apparent solution to that problem was to add ?web=1 at the end of the link.

I followed this link to a similar Q on stack, and I also followed a subsequent link to deal with exceptions but it was for C# and powershell, and I was not totally following.

SharePoint 2010: Open .webpart file in Web Part Gallery in browser like .xml file

Is there a way to modify the link that will force the file to either be opened via the appropriate office program or conversly downloaded so the file can be opened locally by the appropriate app? Opening would be prefered over downloading, but I am open to both.

This is what I am getting when I follow my current links:

example 1

What I should be getting (MS Word in this case): Example 2

The current link format I am using is: