/*
 * Copyright 2006 Wyona
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.wyona.org/licenses/APACHE-LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.wyona.yanel.impl.resources;

import org.wyona.yanel.core.Path;
import org.wyona.yanel.core.Resource;
import org.wyona.yanel.core.api.attributes.ViewableV2;
import org.wyona.yanel.core.attributes.viewable.View;
import org.wyona.yanel.core.attributes.viewable.ViewDescriptor;
import org.wyona.yanel.core.source.YanelRepositoryResolver;

import org.wyona.yarep.core.RepositoryException;
import org.wyona.yarep.core.Repository;

import org.apache.log4j.Category;

import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.MimeConstants;

import java.io.File;
import java.io.InputStream;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

/**
 *
 */
public class PDFResource extends Resource implements ViewableV2 {
    
    private static Category log = Category.getInstance(PDFResource.class);
    
    /**
     *
     */
    public PDFResource() {
        
    }
    
    /**
     *
     */
    public ViewDescriptor[] getViewDescriptors() {
        return null;
    }    
        
    /**
     *
     */
    public View getView(String viewId) {
        View defaultView = new View();
        defaultView.setMimeType(getMimeType(viewId));
        defaultView.setResponse(false); // This resource writes directly into the response output stream
       
        try {
            String yanelPath = getResourceConfigProperty("yanel-path");
            Repository repo = getRealm().getRepository();
            InputStream docSource;
            if (yanelPath != null) {
                docSource = repo.getNode(yanelPath).getInputStream();
            } else {
                docSource = repo.getNode(getPath()).getInputStream();
            }
            
            // Step 1: Construct a FopFactory
            // (reuse if you plan to render multiple documents!)
            FopFactory fopFactory = FopFactory.newInstance();

            // Step 2: Construct fop with desired output format
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, getResponse().getOutputStream());

            YanelRepositoryResolver yanelRepoResolver = new YanelRepositoryResolver(this);
            fopFactory.setURIResolver(yanelRepoResolver);
            
            /* Only for debugging ...
            java.io.FileOutputStream fout = new java.io.FileOutputStream("/home/michi/Desktop/yanel.pdf");
            driver.setOutputStream(fout);
            */

            // TODO: This doesn't seem to work properly (see below)
            //java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
            //driver.setOutputStream(baos);
            
            Transformer transformer = TransformerFactory.newInstance().newTransformer(getXSLTStreamSource(getPath(),repo));           
            
            org.xml.sax.XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
            xmlReader.setEntityResolver(new org.apache.xml.resolver.tools.CatalogResolver());
            Source src = new SAXSource(xmlReader, new org.xml.sax.InputSource(docSource));
            
            Result res = new SAXResult(fop.getDefaultHandler());
            
            transformer.transform(src,res);
            
            // TODO: For some strange reason the stream seems to be truncated after a certain length ...!
            //log.debug("Result Size"+ baos.size());
            //defaultView.setInputStream(new java.io.ByteArrayInputStream(baos.toByteArray()));
        } catch(Exception e) {
            log.error(e, e);
        }        

        return defaultView;     
    }
    
    /**
    *
    */
    public boolean exists() throws Exception {
        log.warn("Not implemented yet!");
        return true; 
    }
    
    /**
     * 
     */
    public long getSize() throws Exception {
        return getRealm().getRepository().getSize(new Path(getPath()));
    }
      
    /**
     *
     */
    private StreamSource getXSLTStreamSource(String path, Repository repo) throws Exception {
        String xsltPath = getXSLTPath(path);
        if(xsltPath != null) {
            return new StreamSource(repo.getInputStream(new Path(xsltPath)));
        } else {
            File xsltFile = org.wyona.commons.io.FileUtil.file(
            rtd.getConfigFile().getParentFile().getAbsolutePath(), "xslt" + File.separator + "xml2fo.xsl");
            log.debug("XSLT file: " + xsltFile);
            return new StreamSource(xsltFile);
        }
    }

    /**
     * 
     */
    private String getXSLTPath(String path) throws Exception {
        String xsltPath = getResourceConfigProperty("xslt");
        if (xsltPath != null) return xsltPath;
        log.info("No XSLT Path within: " + path);
        return null;
    }

    /**
     *
     */
    public String getMimeType(String viewId) {
        return "application/pdf";
    }
}

@@ -919,31 +919,22 @@
 .source.
-YanelRepository
+Source
 Resolver
@@ -2308,18 +2308,25 @@
 ocSource
+ = null
 ;%0A
-
         
@@ -2346,32 +2346,378 @@
 Path != null) %7B%0A
+                if (yanelPath.startsWith(%22yanelrepo:%22) %7C%7C yanelPath.startsWith(%22yanelresource:%22)) %7B%0A                    SourceResolver resolver = new SourceResolver(this);%0A                    Source source = resolver.resolve(yanelPath, null);%0A                    docSource = ((StreamSource) source).getInputStream();%0A                %7D else %7B%0A    
                 
@@ -2762,32 +2762,50 @@
 tInputStream();%0A
+                %7D%0A
             %7D el
@@ -3259,71 +3259,47 @@
     
-YanelRepositoryResolver yanelRepoResolver = new YanelRepository
+SourceResolver srcResolver = new Source
 Reso
@@ -3352,17 +3352,11 @@
 ver(
-yanelRepo
+src
 Reso

use resolved