FOP: how to specify image src relative path? - jsf-2

This is my first question here, i hope i'm doing it right. Sorry for my bad English in advance :)
I am using JSF 2.0 (Eclipse IDE) and i'm trying to generate some PDF files using Apache FOP 1.0.
I was able to make simple PDF files using instructions on Apache Fop site , but i can't insert any image from my application folder. My folder structure is like this:
In my application WebContent i have (among else)
pdf_transform/xslt/transformFile.xsl, and
pdf_transform/xslt/logo.jpg
In transformFile.xsl i have
<fo:block><fo:external-graphic src="url('logo.jpg')"/></fo:block>
but when i clik 'showPDF' button in my servlet, i get PDF file without image (everything else is there), and this messages in console:
SEVERE: The Source that was returned
from URI resolution didn't contain an
InputStream for URI: logo.jpg Nov 18,
2010 5:16:49 PM
org.apache.fop.events.LoggingEventListener
processEvent SEVERE: Image not found.
URI: logo.jpg. (No context info
available)
I tried to use 'logo.jpg' instead of url('logo.jpg'), putting image on various places inside WebContent folder and using different navigation("./logo.jpg") but it didnt work.
It works fine if i set absolute path (for example "d:/fop/images/logo.jpg") but i need resurces whitin my application.
While searching, i found that this is related to fopFactory.setURIResolver() and/or userAgent.setBaseURL(). Tried something with that, but didnt succeed.
I am new to both JSF and FOP, and this image situation has been bothering me quite a while. Can someone help me with this, or at least direct me to some tutorial on "how to configure FOP for relative path use"?
EDIT: I don't want any absolute paths and app should work independently of its location on computer (to be publishable). My search tells me it has something to do with configuring FOP, but i don't know how to do it :)
Thanks in advance.
P.S. This is method which is called to display PDF:
public void printExchangeRateList(ActionEvent event) {
BufferedOutputStream output = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
String path = externalContext.getRealPath("/");
try {
response.reset();
response.setHeader("Content-Type", "application/pdf");
output = new BufferedOutputStream(response.getOutputStream(), 10240);
File xsltfile = new File(path+"/pdf_transform/xslt/transformFile.xsl");
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltfile));
Source src = new DOMSource(makeXML()); // my method
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
} finally {
if (output != null) output.close();
/*try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
} catch (Exception e) {
// TODO Auto-generated catch block
}
facesContext.responseComplete();
}

i found solution to my problem. I thought i tried that, but it seems i made some little mistake back then. Anyway, with the following code
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String basePath = externalContext.getRealPath("/");
FopFactory fopFactory = FopFactory.newInstance();
fopFactory.setBaseURL(basePath);
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.setBaseURL(fopFactory.getBaseURL());
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output); // for some output
you can access your images (and other resources) from your xslt file using relative path starting from your application's WebContent folder. In my case, i can access logo.jpg like this
<fo:external-graphic src="url('pdf_transform/xslt/logo.jpg')"/>
Took me time to figure out this, i don't get it why no examples with such basic thing on the net (or i can't find them :)
Note: In FOP 2.0 there is no setBaseURL() method. Instead you pass the base URL as a parameter to FopFactory.newInstance(). Many of the other setters have been moved to FopFactoryBuilder.

If you have access to the web url for the pictures you can use that as well when generating reports, ie http://localhost/images/logo.jpg .
But while I still had images locally on the web server, I included the path to the application in the XML file and used it like this:
<xsl:variable name="base_path" select="base-path"/>
<xsl:variable name="logo" select="companies/company/logo"/>
<fo:external-graphic src="url({$base_path}{logo})"/>
Where the XML structure might be something like this:
<?xml version="1.0" encoding="UTF-8"?>
<base-path>/path/to/app/</base-path>
<companies>
<company>
<logo>images/company1.jpg</logo>
</company>
<company>
<logo>images/company2.jpg</logo>
</company>
</companies>

I had the same problem and tried this solution:
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
Request request = RequestCycle.get().getRequest();
//sort of a hack to find the path to the files that are in /img folder.
String baseUrl = request.getUrl().getProtocol()+"://"+request.getUrl().getHost()+":"+request.getUrl().getPort();
foUserAgent.setBaseURL(baseUrl);
Then, on XSL I used:
<fo:external-graphic src="/img/image.png" />
To test if this is working, you should be able to see the image on protocol://link:port/img/image.png

Related

How to read a file in src/main/resources in grails

This has been asked before, and I have tried each proposed solution, but all fail.
I have put a javascript file (hl.js) in myapp/src/main/resources
I have tried to read it with the following code taken from the "solutions":
1 - getRsourcesAsStream. returns null inputstream.
InputStream is = this.class.classLoader.getResourceAsStream("hl.js")
2 - getResource - returns null
File myFile = grailsApplication.mainContext.getResource("hl.js").file
3 - getResourceAsStream with classloader - returns null.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream is = classLoader.getResourceAsStream("hl.js");
Interestingly, if I do the following:
String fileNameAndPath = this.class.classLoader.getResource("hl.js").getFile()
System.out.println(fileNameAndPath);
File file = new File(fileNameAndPath)
InputStream is = file.newInputStream();
This prints out:
/Users/me/dev/grails_projects/myapp/src/main/resources/hl.js
But "is" is always null.
I an trying to get an input stream so I can evaluate the javascript via nashorn:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(is)
Grails 3.3.8
Any ideas?
Get the resource and open a stream on it.
def resource = this.class.classLoader.getResource('conf.json')
def path = resource.file // absolute file path
return resource.openStream() // input stream for the file
Source: https://www.damirscorner.com/blog/posts/20160313-AccessingApplicationFilesFromCodeInGrails.html
Well, I dont know why the solutions 1, 2 and 3 do not work, but I found a more long winded way which does work. The main issue is that there are lots of different implementations of eval(), and netbeans "go to declaration" has never worked (presumably some configuration issue in netbeans).
It turns out that the eval() version i happen to be using is expecting a Reader, where as the default documentation shows it needs in InputStream. Also, reader is not the same as InputStreamReader.
This is the solution I found:
import javax.script.ScriptEngine
import javax.script.ScriptEngineManager
import org.grails.core.io.ResourceLocator
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
String fileNameAndPath = this.class.classLoader.getResource("hl.js").getFile()
System.out.println(fileNameAndPath);
File file = new File(fileNameAndPath)
System.out.println("exists: " + file.exists())
Reader reader = file.newReader();
engine.eval(reader)

Sharing violation on path in xamarin

I'm very new to Android programming. I have a code which creates a file in a designated folder and then tried to write something to it. Like below:
path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
var filename = Path.Combine(path, "Test.xml");
Directory.CreateDirectory (path);
if (!File.Exists (path + "/" + "Test.xml")) {
File.Create (path + "/" + "Test.xml");
}
using (var streamWriter = new StreamWriter(filename, true))
{
streamWriter.WriteLine("<?xml version='1.0' encoding='utf-8'?>");
streamWriter.WriteLine ("<Apples>");
streamWriter.WriteLine ("</Apples>");
}
In line using (var streamWriter = new StreamWriter(filename, true)), I'm getting the Sharing Violation on path error.
Could someone please point me as to exactly where I'm going wrong and provide me a solution.
Thanks,
Anirban
Why do you create the file then reopen it to write to it. StreamWriter has an method that will do just that. It will create a new file if it doesn't exist.
Initializes a new instance of the StreamWriter class for the specified file on the specified path, using the default encoding and buffer size. If the file exists, it can be either overwritten or appended to. If the file does not exist, this constructor creates a new file.
StreamWriter could not access the file because File.Create returned a FileStream you did not consume.
As mentioned above, the File.Create is not necessary. You could also use:
using (var writer = new StreamWriter(File.Create(statusTxtPath)))
{
// do work here.
}
which will consume the file stream and close it. Whenever working with streams and most classes that interact with streams, be sure to use the using() block to ensure handles are released properly.
Ok...I have managed to resolve the issue...by using
using (var streamWriter = new StreamWriter (File.Create (path + "/" + "DoctorsList.xml")))

Read text from an URL on Codename One

I'm relatively new to codename one. I'm trying to read text from a pure text url and store the text in a string. I tried using the java IO package but for some reason it doesn't seem to wirk with codename one. Please help.
David.
I think you might not really understand codenameone seeing as you tried to use the Java IO package. But anyway, this code might get you along
ConnectionRequest r = new ConnectionRequest();
r.setUrl("YOURURLHERE");
r.setPost(false);
r.addResponseListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
try
{
NetworkEvent event = (NetworkEvent) ev;
byte[] data= (byte[]) event.getMetaData();
String decodedData = new String(data,"UTF-8");
System.out.println(decodedData);
} catch (Exception ex)
{
ex.printStackTrace();
}
}
});
NetworkManager.getInstance().addToQueue(r);
NOTE: Instead of using System.out.println, which works fine for debugging purposes, you probably want to add the text to your application with a GUI component. I'm not sure if this needs to be said, but it won't do any harm stating it again :)

How to add Apache Any23 RDF Statements to Apache Jena?

Basically, I use the Any23 distiller to extract RDF statements from files embedded with RDFa (The actual files where created by DBpedia Spotlight using the xhtml+xml output option). By using Any23 RDFa distiller I can extract the RDF statements (I also tried using Java-RDFa but I could only extract the prefixes!). However, when I try to pass the statements to a Jena model and print the results to the console, nothing happens!
This is the code I am using :
File myFile = new File("T1");
Any23 runner= new Any23();
DocumentSource source = new FileDocumentSource(myFile);
ByteArrayOutputStream outA = new ByteArrayOutputStream();
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()); //convert the output stream to input so i can pass it to jena model
TripleHandler writer = new NTriplesWriter(outA);
try {
runner.extract(source, writer);
} finally {
writer.close();
}
String ttl = outA.toString("UTF-8");
System.out.println(ttl);
System.out.println();
System.out.println();
Model model = ModelFactory.createDefaultModel();
model.read(decodedInput, null, "N-TRIPLE");
model.write(System.out, "TURTLE"); // prints nothing!
Can anyone tell me what I have done wrong? Probably multiple things!
Is there any easy way i can extract the subjects of the RDF statements directly from any23 (bypassing Jena)?
As I am quite inexperienced in programming any help would be really appreciated!
You are calling
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()) ;
before calling any23 to insert triples. At the point of the call, it's empty.
Move this after the try-catch block.

ImageResizer and image files without an extension

I've been using ImageResizer.net just fine in our web app, but now I need it to resize and serve images that don't (and cannot) have a file extension, like this one:
http://localhost:58306/ClientImages/Batch/2012/12/10/f45198b7c452466684a4079de8d5f85f?width=600
In this situation, I know that my files are always TIFF's, but they wont have a file extension.
What are my options?
/resizer.debug.ashx: https://gist.github.com/raw/9c867823c983f0e5be10/4db31cb21af8b9b36f0aa4e765f6f459ba4b309f/gistfile1.txt
Update
I followed Computer Linguist's instructions:
protected void Application_Start()
{
Config.Current.Pipeline.PostAuthorizeRequestStart +=
delegate
{
var path = Config.Current.Pipeline.PreRewritePath;
var clientImgsRelPath = PathUtils.ResolveAppRelative("~/ClientImages/");
var isClientImageRequest = path.StartsWith(clientImgsRelPath, StringComparison.OrdinalIgnoreCase);
if (isClientImageRequest)
Config.Current.Pipeline.SkipFileTypeCheck = true;
};
// other app start code here
}
http://localhost:58306/ClientImages/Batch/2012/12/10/92d67b45584144beb5f791aaaf760252?width=600 just responds with the original image with no resizing.
This was also asked about here: http://imageresizing.net/docs/howto/cache-non-images#comment-571615564
This is happening during development with the Cassini or Visual Studio web server or whatever you want to call it.
First, you MUST be using IIS7 Integrated mode. Classic mode will not work; it does not permit ASP.NET access to extensionless requests
ImageResizer can't know that extension-less URLs are images unless you explicitly tell it.
This doc explains:
http://imageresizing.net/docs/howto/cache-non-images
Essentially, you'll end up performing logic (usually String.StartsWith) on your URLs to find out if ImageResizer should treat the file as an image.
Config.Current.Pipeline.PostAuthorizeRequestStart += delegate(IHttpModule sender, HttpContext context) {
string path = Config.Current.Pipeline.PreRewritePath;
//Skip the file extension check for everything in this folder:
if (path.StartsWith(PathUtils.ResolveAppRelative("~/folder/of/images"),
StringComparison.OrdinalIgnoreCase)){
Config.Current.Pipeline.SkipFileTypeCheck = true;
}
};
You should register this event handler in Application_Start in global.asax.

Resources