1 Reply Latest reply on Aug 13, 2007 7:05 AM by Champion Louis

    Question concerning remoting

    Champion Louis Newbie

      Hi,
      I have a little problem that i cannot resolve, and I wanted to known your point of vue concerning my problem.
      I'am using :
      - EJB3
      - SEAM 1.2.1-GA
      - JPBM 3.1.4
      - JRules 3.0.8
      - ....

      My problem is in a part of the application I need to generate forms using xml and xsl transformation. I have worked a lot on this point and everything is working fine except the upload of files. I'm explaining the problem.

      I'am using :

       @In (value="#{facesContext.externalContext}")
       private ExternalContext extCtx;
      


      With this I can get all the data submitted, and with JAXB (classes generated from the xsd of the xml file) I stock the new xml with all the data into an eXist Database (xml database).
      My problem is concerning the part where I need to download a file that where submitted to consult it. Due to the fact that I could map use jsf tag, I wanted to use seam remoting to access a method use to download, but the problem is that I don't have any access to the FaceContext when the javascript call is made...

      I post my test code example :

      The JSF Page :
       <div class="main-part" id="main-part">
      
       <script type="text/javascript" src="../seam/resource/remoting/resource/remote.js"></script>
       <script type="text/javascript" src="../seam/resource/remoting/interface.js?fileAction"></script>
      
       <script type="text/javascript">
       //<![CDATA[
      
       Seam.Remoting.setDebug(true);
      
       function download(fileName) {
       Seam.Component.getInstance("fileAction").downloadFromRemoteJavascript(fileName , downloadCallback);
       }
      
       function downloadCallback(result) {
       alert(result);
       }
      
       // ]]>
       </script>
      
       <h:form id="form1" name="form1" enctype="multipart/form-data">
      
       <f:subview rendered="#{testAction.fileName!=null}">
       <a href="#" onclick="javascript:download('#{testAction.fileName}');">Download #{testAction.fileName}</a><br/>
       </f:subview>
      
       File : <input type="file" id="idFileInput" name="nameFileInput" title="titleFileInput" /><br />
      
       <div class="breaker" />
       <h:commandButton action="#{testAction.submit}" value="Submit" />
      
      
       </h:form>
      
       </div>
      


      The coordination Action Bean that is called when I sumit the form:
      @Name("testAction")
      @Stateful
      public class TestActionBean implements TestAction {
      
       @Logger
       private Log log;
      
       @In (value="#{facesContext.externalContext}")
       private ExternalContext extCtx;
      
       @In(create=true)
       private Processor processor;
      
       @In(create=true)
       private FileManager fileManagerLocal;
      
       private String fileName;
      
       @Create
       @Begin(join=true)
       public void begin() {
       log.info("Instanciation de la conversation");
       }
      
       /**
       * @see ...#submit()
       */
       public void submit() {
       log.info("Submit");
      
       try {
      
       //on convertis la request en multipart
       MultipartRequest multipartRequest = (MultipartRequest)extCtx.getRequest();
      
       //dans le cas où on aurait déjà uploadé un fichier, un supprime l'ancien fichier pour que le nouveau le remplace
       if(this.fileName!=null){
       this.fileManagerLocal.deleteFile(this.fileName);
       }
      
       //on crée un objet de type Fichier avec les informations récupéré depuis la request
       Fichier fichier = new Fichier();
       fichier.setFileContentType(multipartRequest.getFileContentType("nameFileInput"));
       fichier.setFileName(multipartRequest.getFileName("nameFileInput"));
       fichier.setFileSize(multipartRequest.getFileSize("nameFileInput"));
       fichier.setFileData(multipartRequest.getFileBytes("nameFileInput"));
      
      
       //on sauvegarde sur le disque le fichier et on conserve le nom unique de ce fichier
      
       this.fileName = FileTools.getFileNameFromUrl(this.fileManagerLocal.saveFile(fichier),"/");
      
       } catch (IOException e) {
       log.error("Error : "+e);
       e.printStackTrace();
       } catch (InterruptedException e) {
       log.error("Error : "+e);
       }
      
       }
      
       ...
      


      The coordination Action Bean called into the javascript :
      @Name("fileAction")
      @Stateless
      public class FileActionBean implements FileAction
      {
       // déclaration du logger
       @Logger
       private Log log;
      
       //Injections des managers situés dans les différentes couches services
       @In(create = true)
       private FileManager fileManagerLocal;
      
       /**
       * @see ...#downloadFromRemoteJavascript
       */
       public boolean downloadFromRemoteJavascript(String fileName){
      
       boolean result = false;
      
       try {
      
       //Récupération de l'object Fichier associé au réglement choisi
       log.info("Recherche du fichier en cours...");
       Fichier fichier = fileManagerLocal.searchFile(FileTools.getFileNameFromUrl(fileName, "/"));
      
       if(fichier != null){
       //this.popupFaceContextFileDownload(fichier);
       result = true;
       }
       else {
       FacesMessages.instance().addFromResourceBundle("file_not_found_exception");
       }
       }
       catch (IOException e) {
       log.error("Erreur lors de la tentative de récupération du fichier nommée "+fileName+" : "+e.getMessage());
       }
      
       return result;
       }
      
       /**
       * Méthode permettant de déclencher le popup de téléchargement du fichier qui a été demandé
       * @param Fichier fichier
       */
       private void popupFaceContextFileDownload (Fichier fichier) throws IOException {
       FacesContext facesContext = FacesContext.getCurrentInstance();
      
       HttpServletResponse response = (HttpServletResponse)facesContext.getExternalContext().getResponse();
      
       response.flushBuffer();
      
       response.setHeader("Content-Disposition", "attachment; filename=\"" + fichier.getFileName() + "\"");
       response.setBufferSize((int)fichier.getFileSize());
       response.setContentLength((int)fichier.getFileSize());
       response.setContentType(fichier.getFileContentType());
      
       ServletOutputStream servletOutputStream = response.getOutputStream();
       servletOutputStream.write(fichier.getFileData());
      
       servletOutputStream.flush();
       servletOutputStream.close();
       response.flushBuffer();
      
       facesContext.responseComplete();
       }
      }
      


      The service manager bean used into the two differents action bean of the coordination layer :

      @Name("fileManagerLocal")
      @Stateless
      public class FileManagerBeanLocal implements FileManager
      {
      
       private static final String FILE_PROPERTIES = "file.properties";
       private Properties properties = new Properties();
      
       @Logger
       Log log;
      
       ....
      
       /**
       * @throws IOException
       * @throws InterruptedException
       * @see ...FileManager#saveFile(java.io.File)
       */
       public String saveFile(Fichier fichier) throws IOException, InterruptedException
       {
      
       // Déclaration :
       String path;
       StringBuffer absolutePath;
       FileOutputStream fileOutputStream;
      
       // Traitement :
       path = properties.getProperty("savePath");
       absolutePath = new StringBuffer();
      
       /* Créer le chemin de sauvegarde */
       absolutePath.append(path).append("/").append(DateTools.getFormattedDateNow()).append("-").append(fichier.getFileName());
       /* Ecriture du fichier */
       fileOutputStream = new FileOutputStream(absolutePath.toString());
       fileOutputStream.write(fichier.getFileData());
       fileOutputStream.flush();
       fileOutputStream.close();
      
       return absolutePath.toString();
       }
      
       /**
       * @throws IOException
       * @see ...#searchFile(java.lang.String)
       */
       public Fichier searchFile(String fileName) throws IOException
       {
       String path = properties.getProperty("savePath") + "/";
       File searchedFile = new File(path + fileName);
       if (searchedFile.exists())
       {
       Fichier fichier = new Fichier();
       fichier.setFileData(this.readFile(searchedFile));
       fichier.setFileName(searchedFile.getName());
       fichier.setFileContentType(new MimetypesFileTypeMap().getContentType(searchedFile));
       fichier.setFileSize(searchedFile.length());
       return fichier;
       }
       else
       return null;
       }
      
       ...
      }
      


      My is that i calling the method downloadFromRemoteJavascript form the fileAction Class when we arrive to the line commented that is calling the private methode popupFaceContextFileDownload :

      FacesContext facesContext = FacesContext.getCurrentInstance();
      


      The current instance is null so i cannot popup the download file. Any suggestion or advise will be welcome...

      Thanks in advance,
      Louis