How to read css file in Java in xpages - java

I would like to read the content of a css file stored in my NSF to include it in the style element in a (HTML) file that I create.
FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream
does not seem to be the way.
Anyone a suggestion?
I tried
InputStream input = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("file.css");
and then
StringBuilder sb = new StringBuilder();
sb.append("<style>").append("\n");
sb.append(convertStreamToString(input)).append("\n");
sb.append("</style>").append("\n");
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
which works fine

You can use Apache Commons IOUtils to copy from the InputStream to a StringWriter and then use toString() on the StringWriter. Here's a simple method that does that:
private static String getResourceFile(final String filename) {
final InputStream input = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream(filename);
final StringWriter writer = new StringWriter();
try {
IOUtils.copy(input, writer, "utf-8");
} catch (final IOException e) {
System.out.println("Error reading: " + filename);
}
return writer.toString();
}

Related

What are the file output limits with my code?

I just made a very simple parser that gets input from a file and outputs to a file.
It does a line-by-line parsing of the file you give it and iterates the same function for all lines of the file and then it redirects the whole string to another file.
I give the parseLine function a JsonObjectBuilder so that it can keep on adding json-like structures to the output string (it's a normal text to json parser btw).
parseFile function
private String parseFile(String file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader (file));
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
String line;
try{
while((line = reader.readLine()) != null){
parseLine(line, jsonBuilder);
}
} finally {
reader.close();
}
return jsonBuilder.build().toString();
}
Parser class
public Parser(String file) throws IOException {
PrintWriter out = new PrintWriter(System.getProperty("user.dir") + "/parser/src/main/resources/logFormatted.log");
System.out.println("Initiated Parser class!");
out.println(parseFile(file));
}
parseLine function
private JsonObjectBuilder parseLine(String line, JsonObjectBuilder jsonBuilder){
String timestamp = null;
String eventCode = null;
String payload = null;
String finalString = null;
try {
timestamp = line.substring(0, 23);
eventCode = line.substring(24, 28);
payload = line.substring(29, line.length());
jsonBuilder.add(timestamp, Json.createObjectBuilder()
.add("eventCode", eventCode)
.add("payload", payload)
);
} catch (Exception ex) {
System.out.println("ERROR: " + ex);
}
return jsonBuilder;
}
Main
public static void main( String[] args ) throws IOException{
Parser parser = new Parser(System.getProperty("user.dir") + "/parser/src/main/resources/newFormatLog.log");
}
The problem with this code is that when it's executed it parses like it's supposed to but doesn't parse the whole file. Right now I'm giving it a ~4550 lines file but it does output a ~4400 line one.
I really don't know why and I'm starting to think the string is too big to handle or something. Maybe I need to output the lines immediatly to the file rather than doing a final big wite. All help is very appreciated!
Found out the problem. It was really dumb.
public Parser(String file) throws IOException {
PrintWriter out = new PrintWriter(System.getProperty("user.dir") + "...");
System.out.println("Initiated Parser class!");
out.println(parseFile(file));
}
In this constructor I was not closing the PrintWriter. Just added out.close(); and everything worked as expected.
public Parser(String file) throws IOException {
try (PrintWriter out = new PrintWriter(System.getProperty("user.dir") + "...")) {
System.out.println("Initiated Parser class!");
out.println(parseFile(file));
}
}
You can refer to this other question as reference.
EDIT: Added try(PrintWriter out = ...) as suggested in the comments

How to read file from network path?

Basic explanation:
I'm coding a simple java utility which will take xml file and convert it into html. All xml files have same structure and need to be converted into same looking HTML file so i chose to code it using BufferedReader and Writer, see code below.
I'm having following problem If i'm using file that is on local disk, than there is no problem and everything workes fine, but when i try to use file that is on connected shared network disk, code throws exception.
this is whole code
reading and writting file that is stored in project folder workes just fine and just as i want to, i'm only having problem with file stored on network disk.
public static void main(String[] args) {
String cestaKsuboruXml = "file.xml"; //workes fine
//this one throws error
// String cestaKsuboruXml = "\\172.27.20.38\eDesk\2017\0925\144f7d8d-3786-4858-95ef-bb853c41b713\1_PridelenieCislaPodania.xml";
//class which contains html code
sablonaJedna sablonaJedna = new sablonaJedna();
String fileName = null ;
String line = null;
StringBuilder text = new StringBuilder();
StringBuilder subject = new StringBuilder();
try {
FileReader fileReader = new FileReader(cestaKsuboruXml);
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(new FileInputStream(cestaKsuboruXml), "UTF-8"));
while ((line = bufferedReader.readLine()) != null) {
if (line.contains("<subject>")) {
subject.append(line);
}
if (!line.contains("<GeneralAgenda") && !line.contains("<subject>"))
{
text.append(line);
}
}
} catch (IOException ex) {
System.out.println("Exception");
}
String text2 = text.toString();
String subject2 = subject.toString();
subject2 = subject2.replace("<subject>", "");
subject2 = subject2.replace("</subject>", "");
text2 = text2.replace("<text>", "");
text2 = text2.replace("</text>", "");
text2 = text2.replace("</GeneralAgenda>", "");
try {
BufferedWriter writer = new BufferedWriter
(new OutputStreamWriter(new FileOutputStream("vvvaa.html", true), "UTF-8"));
writer.write(sablonaJedna.getSablonaCss() + sablonaJedna.getSablonaHtml() + subject2 +
"</span></div><div class=\"clear\"> </div><div><label class=\"labelVis\">Text: </label> <span class=\"contentVis wordwrap\">"
+ text2 + "</span></div><div class=\"clear\"> </div></div></div></body></html>"
);
writer.close();
} catch (IOException xx) {
System.out.println("Exception");
}
}
all i had to do was use this as a source:
String cestaKsuboruXml = "\\\\172.27.20.38\\eDesk\\2017\\0925\\144f7d8d-3786-4858-95ef-bb853c41b713\\1_PridelenieCislaPodania.xml";
so two more backslashes at the start of a link

Create CSV file without saving it into file system

I've created a Java program to create a csv file, write data into it and then send its contents to the server.
Locally, everything works fine. But the problem is that I don't have write access to the server (permission denied problem).
So, I can't do any chmod 777.
I'm looking for a way to create a csv file without saving into the file system. Something like write into a flow or a stream. I don't really know how it works.
Any help please ?
This was what I have done so far:
public void exportAllToCSV(#PathVariable int id,HttpServletResponse response) throws IOException
String csvFile="test.csv";
File file = new File("test.csv");
//some treatments to get datas (headers and values)
FileWriter writer = new FileWriter(csvFile);
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
writer.close();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=" + csvFile);
final BufferedReader br = new BufferedReader(new FileReader(file));
try {
String line;
while ((line = br.readLine()) != null) {
response.getWriter().write(line + "\n");
}
} finally {
br.close();
}
try {
file.delete(); // I delete the file
} catch (Exception e) {
e.printStackTrace();
}
You can try to write directly to response:
Writer writer = response.getWriter();
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
writer.close();
response.setContentType("text/csv");
response.setHeader("Content-Disposition","attachment; filename=" + csvFile);
If that can not be used for some reason and temporary files are also not allowed for you, you can try to use this pretty ugly in-memory variant.
List<Integer> output = new LinkedList<>();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new OutputStream() {
#Override
public void write(int b) throws IOException {
output.add(b);
}
}));
// write all the things via CsvBuilder
final BufferedReader reader = new BufferedReader(new InputStreamReader(new InputStream() {
#Override
public int read() throws IOException {
if (output.size() > 0) {
return output.remove(0);
}
return -1;
}
}));
Assuming that CsvBuilder.writeLine(...) does only accept an instance of java.io.Writer, why not using java.io.StringWriter and java.util.Scanner?
// ...
StringWriter writer = new StringWriter();
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=test.csv");
Scanner scanner = new Scanner(new StringReader(writer.toString()));
while (scanner.hasNext()) {
response.getWriter().write(scanner.next() + "\n");
}
// ...
However, I think Andrei Makarevich's answer using response.getWriter() directly is probably the most forward approach. Although, I'm not sure if the line feeds will be added by CsvBuilder since your adding them explicitly!?
You can try, if temporary files are allowed:
File temp = File.createTempFile("test.csv", ".csv");
These files are getting created in the user storage of the system, so like "C:\Users[Username]\AppData" in Windows, or something like that. I don't know the exact path, but that should not be important now.
Check out all the kinds of OutputStreams, that exist in Java, there is more than the FileOutputStream:
https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html
Check the subclasses.
Incase someone still looking for the answer, below code worked for me perfectly
Import the below dependencies
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
Below code, im writing data to ByteArrayOutputStream, instead of FileWriter
ByteArrayOutputStream out = new ByteArrayOutputStream();
CsvWriter csvWriter = new CsvWriter(new BufferedOutputStream(out), ',', Charset.forName("UTF-8"));
String[] data = new String[] { "fieldValueA", "fieldValueB", "fieldValueC" };
csvWriter.writeRecord(data);
csvWriter.close();
You can use StringBuilderWriter to have a writer instead of FileWriter
final Writer writer = new StringBuilderWriter();

Read and Write Text in ANSI format

Please have a look at the following code
import java.io.*;
public class CSVConverter
{
private File csvFile;
private BufferedReader reader;
private StringBuffer strBuffer;
private BufferedWriter writer;
int startNumber = 0;
private String strString[];
public CSVConverter(String location, int startNumber)
{
csvFile = new File(location);
strBuffer = new StringBuffer("");
this.startNumber = startNumber;
//Read
try
{
reader = new BufferedReader(new FileReader(csvFile));
String line = "";
while((line=reader.readLine())!=null)
{
String[] array = line.split(",");
String inputQuery = "insertQuery["+startNumber+"] = \"insert into WordList_Table ('Engl','Port','EnglishH','PortugueseH','Numbe','NumberOf','NumberOfTime','NumberOfTimesPor')values('"+array[0]+"','"+array[2]+"','"+array[1]+"','"+array[3]+"',0,0,0,0)\"";
strBuffer.append(inputQuery+";"+"\r\n");
startNumber++;
}
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(strBuffer.toString());
//Write
try
{
File file = new File("C:/Users/list.txt");
FileWriter filewrite = new FileWriter(file);
if(!file.exists())
{
file.createNewFile();
}
writer = new BufferedWriter(filewrite);
writer.write(strBuffer.toString());
writer.flush();
writer.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[]args)
{
new CSVConverter("C:/Users/list.csv",90);
}
}
I am trying to read a CSV file, edit the text in code, and write it back to a .txt file. My issue is, I have Portuguese words, so the file should be read and write using ANSI format. Right now some Portuguese words are replaced with symbols in the output file.
How can I read and write text data into a file in ANSI format in Java?
To read a text file with a specific encoding you can use a FileInputStream in conjunction with a InputStreamReader. The right Java encoding for Windows ANSI is Cp1252.
reader = new BufferedReader(new InputStreamReader(new FileInputStream(csvFile), "Cp1252"));
To write a text file with a specific character encoding you can use a FileOutputStream together with a OutputStreamWriter.
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "Cp1252"));
The classes InputStreamReader and OutputStreamWriter translate between byte oriented streams and text with a specific character encoding.

How do I convert an InputStream to a String in Java?

Suppose I have an InputStream that contains text data, and I want to convert this to a String (for example, so I can write the contents of the stream to a log file).
What is the easiest way to take the InputStream and convert it to a String?
public String convertStreamToString(InputStream is) {
// ???
}
If you want to do it simply and reliably, I suggest using the Apache Jakarta Commons IO library IOUtils.toString(java.io.InputStream, java.lang.String) method.
This is my version,
public static String readString(InputStream inputStream) throws IOException {
ByteArrayOutputStream into = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
for (int n; 0 < (n = inputStream.read(buf));) {
into.write(buf, 0, n);
}
into.close();
return new String(into.toByteArray(), "UTF-8"); // Or whatever encoding
}
String text = new Scanner(inputStream).useDelimiter("\\A").next();
The only tricky is to remember the regex \A, which matches the beginning of input. This effectively tells Scanner to tokenize the entire stream, from beginning to (illogical) next beginning...
- from the Oracle Blog
Since Java 9 InputStream.readAllBytes() even shorter:
String toString(InputStream inputStream) throws IOException {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); // Or whatever encoding
}
Note: InputStream is not closed in this example.
You can use a BufferedReader to read the stream into a StringBuilder in a loop, and then get the full contents from the StringBuilder:
public String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Full disclosure: This is a solution I found on KodeJava.org. I am posting it here for comments and critique.
A nice way to do this is using Apache commons IOUtils
IOUtils.toString(inputStream, string);

Categories