Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ListGridFieldType.BINARY / File Download

    I'm using SmartGWT Power 2.5, using both Chrome and IE.

    I've created a field in a list grid with type BINARY:
    Code:
            final ListGridField getField = new ListGridField("filename",
                                                             "Log Files");
            getField.setType(ListGridFieldType.BINARY);
    but the view & download icons never appear on my grid, just the filename. I don't get any errors or warnings.

    There don't seem to be any examples in the showcase of the BINARY field, and only the brief description in the javadocs.

    Do I need to do something to make the icons appear?

    #2
    There are both Hibernate and SQL Upload examples that also show download.

    View and download icons will not be shown for a generic binary field where we don't know what it contains - see the sample and choose among other binary field types listed in the docs.

    Comment


      #3
      I've been looking through the Showcase but I can't seem to find which example actually has file downloading capability. None of the listgrid examples have names (or thumbnails) that indicate file downloads.

      I've been through the Javadocs and the Quick Start guide and I've tried the ony other ListGridFieldType that seems to make sense (IMAGEFILE) but no luck with that.

      Which 'examples' and 'docs' are you referring to?

      Comment


        #4
        The File Upload sample we referred you to also shows download icons (click View as List).

        Comment


          #5
          Does the download/view feature work with non-sql/non-hibernate datasources? I'm using a custom datasource built on the SmartGWT Server Framework

          Code:
          <DataSource
          	ID="logFile"
          	schemaBean="com.integral.JBridge.server.log.LogFileData"
          	serverConstructor="com.integral.JBridge.server.log.LogFileDataSource"
          	dropExtraFields="true" >
              <fields>
                  <field name="uid" hidden="false" type="integer" />
                  <field primaryKey="true" name="filename" type="imageFile" />
                  <field name="size" type="integer" />
              </fields>
          </DataSource>

          Comment


            #6
            Yes, it does. For an upload, you have dsRequest.getUploadFile() to get the inbound InputStream. For a download, just have your DMI logic or custom DataSource return any valid Record format (Map, Java Bean, etc) that has an InputStream as a field value.

            Comment


              #7
              Is there an example of a custom datasource that provides the necessary InputStream?
              I still can't get the ListGridField to show the view/download icons :(

              Comment


                #8
                Whether the actual response contains a correct InputStream has nothing to do with whether icons are shown. The UI will show them regardless for a field of type "imageFile". Again there's that very simple example in the Showcase - use the right field type, and you're done. If you're having trouble with this, just remove all code except the DataSource definition and the grid binding to it, note that works, then re-introduce code until you figure out what went wrong.

                See the QuickStart Guide section on "Returning Data" to understand the different data formats that can be returned. Again the InputStream should be a field value.

                Comment


                  #9
                  Well, I've given up on having the view/download icons appear. No matter what I do they won't show up.

                  I'm working around it by having a download button outside of my ListGrid that invokes DataSource.downloadFile() for each selected record in the ListGrid.

                  It took a while to figure out how to prepare the DSRequest (loading the OldValues) so that the server knows which file to send. Setting parameters and attributes didn't work.
                  Code:
                              public void onClick(final ClickEvent aEvent)
                              {
                                  final ListGridRecord record = mFileGrid.getSelectedRecord();
                                  if (record != null)
                                  {
                                      final DSRequest dsRequest = new DSRequest();
                  
                                      dsRequest.setData(record);
                                      dsRequest.setOldValues(record);
                                      mFileGrid.getDataSource().downloadFile(record,
                                                                             "fileStream",
                                                                             dsRequest);
                                  }
                              }
                  Code:
                  <DataSource
                  	ID="logFile"
                  	schemaBean="com.company.app.server.log.LogFileData"
                  	serverConstructor="com.company.app.server.log.LogFileDataSource"
                  	dropExtraFields="true" >
                      <fields>
                          <field name="uid" hidden="false" type="integer" />
                          <field primaryKey="true" name="fullPath" type="text" />
                          <field name="shortName" type="text" />
                          <field name="fileStream" type="binary" />
                          <field name="size" type="integer" />
                      </fields>
                  	<operationBindings>
                          <binding operationType="downloadFile" >
                              <serverObject className="com.company.app.server.log.LogFileDataSource"
                  		                  methodName="downloadFile" />
                         </binding>
                      </operationBindings>
                  </DataSource>
                  Unfortunately, in both Chrome and IE (I haven't tried Firefox 9 due to lack of GWT support) I end up with a page that has just a text area that contains:
                  Code:
                  //isc_RPCResponseStart-->[{endRow:0,queueStatus:0,totalRows:1,isDSResponse:true,invalidateCache:false,status:0,startRow:0,data:{fullPath:"Logs/App.log.2011-12-31",shortName:"App.log.2011-12-31",size:1891,uid:68}}]//isc_RPCResponseEnd
                  The browser shows the URL of:
                  Code:
                  http://localhost:2880/app/sc/IDACall?isc_rpc=1&isc_v=SC_SNAPSHOT-2011-08-02&isc_tnum=3

                  Here's the downloadFile() function from my datasource:
                  Code:
                      public DSResponse downloadFile(final DSRequest aReq)
                      {
                          mLog.debug("downloadFile, DSRequest: "
                                     + aReq.toString());
                  
                  
                          final DSResponse response = new DSResponse(this);
                  
                          final LogFileData fileData = new LogFileData();
                          final String fullPath = (String) aReq.getOldValues().get("fullPath");
                  
                          if (fullPath == null)
                          {
                              mLog.error("File path was not specified for Log");
                              response.setFailure();
                              return response;
                          }
                  
                          fileData.setFullPath(fullPath);
                          fileData.setShortName((String) aReq.getOldValues().get("shortName"));
                          fileData.setSize((Long) aReq.getOldValues().get("size"));
                          fileData.setUid(((Long) aReq.getOldValues().get("uid")).intValue());
                  
                          try
                          {
                              fileData.setFileStream(new FileInputStream(fullPath));
                          }
                          catch (final FileNotFoundException e)
                          {
                              mLog.error("Could not create Input Stream for "
                                         + fullPath);
                              response.setFailure();
                              return response;
                          }
                  
                  
                          response.setData(fileData);
                          response.setInvalidateCache(true);
                  
                          //response.setStartRow(0);
                          //response.setEndRow(0);
                          //response.setTotalRows(1);
                          response.setSuccess();
                  
                          //aReq.getRPCManager().doCustomResponse();
                  
                          return response;
                      }
                  I don't have any errors or warnings. I'm guessing that something in my DSResponse isn't quite what downloadFile() wants, but I haven't stumbled upon it yet.
                  Last edited by evanross; 10 Jan 2012, 13:55.

                  Comment


                    #10
                    More man-hours spent fighting with this and still no resolution.

                    From various scraps here and there it seems that the data in the DSResponse is supposed to be a Map<String,Object> that contains the InputStream with the proper field name, right?

                    My downloadFile server function is:
                    Code:
                        public DSResponse downloadFile(final DSRequest aReq)
                        {
                            mLog.debug("downloadFile, DSRequest: "
                                       + aReq.toString());
                    
                    
                            final DSResponse response = new DSResponse(this);
                    
                            final LogFileData fileData = new LogFileData();
                            //final Map<String, Object> values = aReq.getOldValues();
                            final Map<String, Object> values = aReq.getCriteria();
                            final String fullPath = (String) values.get("fullPath");
                    
                            if (fullPath == null)
                            {
                                mLog.error("File path was not specified for Log");
                                response.setFailure();
                                return response;
                            }
                    
                            fileData.setFullPath(fullPath);
                            //fileData.setShortName((String) values.get("shortName"));
                            //fileData.setSize((Long) values.get("size"));
                            //fileData.setUid(((Long) values.get("uid")).intValue());
                    
                            InputStream stream;
                            try
                            {
                                stream = new FileInputStream(fullPath);
                            }
                            catch (final FileNotFoundException e)
                            {
                                mLog.error("Could not create Input Stream for "
                                           + fullPath);
                                response.setFailure();
                                return response;
                            }
                            fileData.setFileStream(stream);
                    
                    
                            //final LogFileData[] dataSet = new LogFileData[1];
                            //dataSet[0] = fileData;
                            //response.setData(dataSet);
                    
                            //response.setData(fileData);
                    
                            final Map<String, Object> responseMap = new HashMap<String, Object>();
                            responseMap.put("fileStream",
                                            stream);
                            response.setData(responseMap);
                    
                            //response.setInvalidateCache(true);
                    
                            //response.setStartRow(0);
                            //response.setEndRow(0);
                            //response.setTotalRows(1);
                            response.setSuccess();
                    
                            mLog.debug("response data is: "
                                       + response.getData().toString());
                            mLog.debug("response data class is: "
                                       + response.getData().getClass());
                            mLog.debug("fileStream is: "
                                       + ((Map<String, Object>) response.getData()).get("fileStream").toString());
                            return response;
                        }
                    The file look up succeeds, the InputStream is created, and then I get the following failure in the server log:
                    Code:
                    === 2012-01-11 17:18:44,686 [8-29] DEBUG com.isomorphic.rpc.RPCManager - Request #1 (DSRequest) payload: {
                        criteria:{
                            fullPath:"Logs/IDC-Bridge.log.2012-01-10",
                            download_fieldname:"fileStream"
                        },
                        operationConfig:{
                            dataSource:"logFile",
                            operationType:"downloadFile"
                        },
                        appID:"builtinApplication",
                        operation:"logFile_downloadFile",
                        oldValues:{
                            fullPath:"Logs/IDC-Bridge.log.2012-01-10",
                            download_fieldname:"fileStream"
                        }
                    }
                    === 2012-01-11 17:18:44,693 [8-29] DEBUG com.isomorphic.base.Reflection - adaptArgsAndInvoke:
                    
                     public com.isomorphic.datasource.DSResponse com.integral.JBridge.server.log.LogFileDataSource.downloadFile(com.isomorphic.datasource.DSRequest)
                    
                    requiredArgs: [] optionalArgs: [com.isomorphic.servlet.RequestContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.ServletContext, javax.servlet.http.HttpSession, com.isomorphic.rpc.RPCManager, com.isomorphic.datasource.DSRequest, com.isomorphic.datasource.DataSource, java.sql.Connection, com.isomorphic.log.Logger, java.util.Map]
                    === 2012-01-11 17:18:44,694 [8-29] DEBUG com.isomorphic.base.Reflection - checking whether type: com.isomorphic.servlet.RequestContext fulfills type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,694 [8-29] DEBUG com.isomorphic.base.Reflection - checking whether type: javax.servlet.http.HttpServletRequest fulfills type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,694 [8-29] DEBUG com.isomorphic.base.Reflection - checking whether type: javax.servlet.http.HttpServletResponse fulfills type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,694 [8-29] DEBUG com.isomorphic.base.Reflection - checking whether type: javax.servlet.ServletContext fulfills type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,694 [8-29] DEBUG com.isomorphic.base.Reflection - checking whether type: javax.servlet.http.HttpSession fulfills type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,694 [8-29] DEBUG com.isomorphic.base.Reflection - checking whether type: com.isomorphic.rpc.RPCManager fulfills type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,694 [8-29] DEBUG com.isomorphic.base.Reflection - checking whether type: com.isomorphic.datasource.DSRequest fulfills type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,695 [8-29] DEBUG com.isomorphic.base.Reflection - Successfully adapted optional arg type: com.isomorphic.datasource.DSRequest to type: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,695 [8-29] DEBUG com.isomorphic.base.Reflection - method takes: 1 args.  I've assembled: 1 args
                    === 2012-01-11 17:18:44,695 [8-29] DEBUG com.isomorphic.base.Reflection - invoking method:
                    com.isomorphic.datasource.DSResponse com.integral.JBridge.server.log.LogFileDataSource.downloadFile(com.isomorphic.datasource.DSRequest)
                    
                    with arg types: com.isomorphic.datasource.DSRequest
                    === 2012-01-11 17:18:44,695 [8-29] INFO  com.isomorphic.datasource.DSResponse - DSResponse: Map with 1 keys
                    === 2012-01-11 17:18:44,696 [8-29] ERROR com.isomorphic.servlet.IDACall - Error executing operation: logFile_downloadFile
                    java.lang.NullPointerException
                    	at com.isomorphic.datasource.DataSource.getProperties(DataSource.java:1550)
                    	at com.isomorphic.datasource.DataSource.getProperties(DataSource.java:1521)
                    	at com.isomorphic.datasource.DataSource.getProperties(DataSource.java:1516)
                    	at com.isomorphic.datasource.DataSource.getProperties(DataSource.java:1482)
                    	at com.isomorphic.datasource.DataSource.getProperties(DataSource.java:1460)
                    	at com.isomorphic.datasource.DSResponse.getRecord(DSResponse.java:868)
                    	at com.isomorphic.rpc.RPCManager.completeResponse(RPCManager.java:747)
                    	at com.isomorphic.rpc.RPCManager.send(RPCManager.java:582)
                    	at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:156)
                    	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:121)
                    	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:73)
                    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
                    	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
                    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
                    	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:538)
                    	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1352)
                    	at com.isomorphic.servlet.CompressionFilter.doFilter(CompressionFilter.java:259)
                    	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1323)
                    	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:476)
                    	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
                    	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:517)
                    	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
                    	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:937)
                    	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
                    	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
                    	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:871)
                    	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
                    	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:247)
                    	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
                    	at org.eclipse.jetty.server.Server.handle(Server.java:346)
                    	at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:589)
                    	at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:1065)
                    	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:823)
                    	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:220)
                    	at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411)
                    	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:531)
                    	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
                    	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529)
                    	at java.lang.Thread.run(Unknown Source)
                    === 2012-01-11 17:18:44,697 [8-29] DEBUG com.isomorphic.datasource.DataSource - In DS.forName() for 'logFile' with DSRequest: com.isomorphic.datasource.DSRequest@54dbb83a
                    === 2012-01-11 17:18:44,697 [8-29] DEBUG com.isomorphic.datasource.DataSource - Creating instance of DataSource 'logFile'
                    === 2012-01-11 17:18:44,699 [8-29] WARN  com.isomorphic.rpc.RPCManager - dsResponse.getData().get("fileStream") returned null  when we were expecting an InputStream. Can't continue.

                    Comment


                      #11
                      Looking at the line numbers, this NPE looks like a bug fixed after release, although from your other declarations it should not have affected you. Regardless, grab the fully patched build from smartclient.com/builds.

                      Comment


                        #12
                        Is the imageFile field type ok for a pdf file? At one point I remember the icons for downloading and viewing were showing up. I am using a nightly build from the 1st of this year. I can't get the icons to show up anymore.

                        Comment


                          #13
                          No, "imageFile" means image data. For a .pdf just use "binary".

                          If you're having trouble with icons, first be sure to try the latest, and if there's still a problem, let us know the version and what your code looks like.

                          Comment


                            #14
                            Any hints about the NullPointerException?
                            Can you tell me what I'm missing in my DSResponse?

                            Comment


                              #15
                              See post #11 - have you tried the patched build?

                              Comment

                              Working...
                              X