cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nils Kaiser <NilsKai...@gmx.net>
Subject Retrieving mimetype set by serializer in pipeline called using flow
Date Thu, 12 Apr 2007 16:57:24 GMT
Hello devs,

I have been using flow to control my pipelines for some kind of cms. I 
use flow to control the pipelines by invoking the PipelineUtil class to 
execute pipelines to an outputstream, which I then send to the client 
via another pipeline and a reader.

In some cases, the called pipelines are returning different mime-types. 
With the methods offered by PipelineUtil, I have no possibility to 
retrieve the mime-type set by the serializer.

What I did is implement a processToStreamEx function that returns me the 
mimetype as a String. I tried around and encoutered the following pitfalls:

1) The members in PipelineUtil are private, which makes it difficult to 
extend this class.

2) The SitemapSource class is final, too.

3) Using SitemapSource, the mimeType was not set. I had to add the 
marked line to getInputStream()

    /**
     * Return an <code>InputStream</code> object to read from the source.
     */
    public InputStream getInputStream()
    throws IOException, SourceException {

        if (this.needsRefresh) {
            this.refresh();
        }
        // VG: Why exception is not thrown in constructor?
        if (this.exception != null) {
            throw new SourceException("Cannot get input stream for " + 
getURI(), this.exception);
        }

        if (this.redirectSource != null) {
            return this.redirectSource.getInputStream();
        }

        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            this.environment.setOutputStream(os);
            CocoonComponentManager.enterEnvironment(this.environment,
                                                    this.manager,
                                                    this.pipelineProcessor);
            try {
                this.processingPipeline.process(this.environment);
            } finally {
                CocoonComponentManager.leaveEnvironment();
            }

--->            this.mimeType = this.environment.getContentType();

            return new ByteArrayInputStream(os.toByteArray());

        } catch (ResourceNotFoundException e) {
            throw new SourceNotFoundException("Exception during 
processing of " + this.systemId, e);
        } catch (Exception e) {
            throw new SourceException("Exception during processing of " 
+ this.systemId, e);
        } finally {
            // Unhide wrapped environment output stream
            this.environment.setOutputStream(null);
            this.needsRefresh = true;
        }
    }

4) To retrieve the mimetype, I made my own PipelineUtil function that 
returns the mimetype

  public String processToStreamEx(String uri, Object viewData, 
OutputStream output)
  throws IOException {
      checkSetup();

      Map objectModel = ContextHelper.getObjectModel(this.context);

      // Keep the previous view data, if any (is it really necessary?), 
and set the new one
      Object oldViewData = FlowHelper.getContextObject(objectModel);
      FlowHelper.setContextObject(objectModel, 
JavaScriptFlowHelper.unwrap(viewData));

      Source src = null;
      InputStream input = null;
--->      String mimetype = null;
      try {
          src = this.resolver.resolveURI("cocoon:/" + uri);
          input = src.getInputStream();
--->          mimetype = src.getMimeType();
          IOUtils.copy(input, output);
--->          return mimetype;
      } finally {
          if (input != null) {
              try {
                  input.close();
              } catch (IOException ignored) {}
          }

          // Restore the previous view data
          FlowHelper.setContextObject(objectModel, oldViewData);

          if (src != null) {
              this.resolver.release(src);
          }
      }
  }

I am not submitting any patch as the solution is only a workaround. 
Maybe it would be better to add a processToOutput method that expects a 
PipelineOutput instead of an Outputstream. The PipelineOutput would 
expect an OutputStream in the constructor, but add a getMimeType() 
function? I'm sure you have more ideas on that...

What do you think?

Nils



Mime
View raw message