FreeMarker get variable value by concatenating another variable value - java

public class Main {
public static void main(String[] args) throws IOException, TemplateException{
Configuration freemarkerConfig = new Configuration();
freemarkerConfig.setClassForTemplateLoading(Main.class, "");
Template template = freemarkerConfig.getTemplate("template.ftl");
Map<String, String> data = new HashMap<String, String>();
for(int i=1;i<=10;i++){
data.put("map_"+i, "value"+i);
}
Writer out = new StringWriter();
template.process(data, out);
System.out.println(out.toString());
}
}
Here is my FTL code to access the variable:
<#assign containerIndex=1>
${map_containerIndex}
This gives error
I want to evaluate ${map_1}

You can read variables with such runtime generated names like .vars['map_' + i]. It's the same trick than tom has used in his answer, but applied for reading a top-level variable.

Instead of trying to create a variable (which I don't think is possible that way) I'd suggest providing an array to the template.
Like so
String[] stringArray = new String[11];
for (int i = 1; i<= 10; i++) {
stringArray[i] = "value"+i;
}
data.put("map", stringArray);
Access in Freemarker should look like
<#assign containerIndex=1>
${map[containerIndex]}
or something like that, can't try it out atm
Also note, that by starting the for-loop with 1 (as in your example) the first array-slot won't be used.
I'd suggest
String[] stringArray = new String[10];
for (int i = 0; i < 10; i++) {
stringArray[i] = "value"+i;
}

Related

How to solve InvocationTargetException in for loop? (seeking entire stack trace)

Currently, I'm having problem with my work.
List<Map<String,String>> tmp = //blahblahblah//(for my privacy)
int size = tmp.size();
String[] linearr = new String[size];
String[] numarr= new String[size];
String[] namearr= new String[size];
String[] datearr= new String[size];
int i = 0;
for (i = 0; i < size; i++) {
linearr[i] = (String) tmp.get(i).get("line").toString();
numarr[i] = (String) tmp.get(i).get("number").toString();
namearr[i] = (String) tmp.get(i).get("name").toString();
datearr[i] = (String) tmp.get(i).get("date").toString();
}
I made a List<Map<String,String>> however when i got to for-loop. InvocationTargetException came up.
And I could not debug anymore and cannot track it
I tried the code surrounds with try and catch block with throws InvocationTargetException e
but Eclipse told me to remove it.
please help
specifically it said that invocationtargetexception.<init>(throwable) line: not available
You may find this link helpful. However, I'd like to suggest that you need to make sure that all keys are available in your map.
P.S. You don't need to use toString() and (String) cast.
You Don't want to use List ? And if you don't have the exact keys in map ,it will throw Exception . Using get or default will prevent it.
List<String> line = new ArrayList<>();
List<String> number = new ArrayList<>();
List<String> name = new ArrayList<>();
List<String> date = new ArrayList<>();
for(Map<String, String> map:tmp){
line.add(map.getOrDefault("line",""));
number.add(map.getOrDefault("number",""));
name.add(map.getOrDefault("name",""));
date.add(map.getOrDefault("date",""));
}

Implementing language locales into array to be used in a loop

I'm trying to read every file in a directory, clean up with java util.locale, then write to a new directory. The reading and writing methods work, the Locale.SPANISH might be the issue as I have read in other posts.
I iterated through the available languages in the java.util.locale, spanish was in there.
First, the array issue: the following extract of code below is the long way of entering the Locale.(LANGUAGE) into the array. This seems to work fine. However, I can't understand why the 'short' way doesn't seem to work.
String[] languageLocale = new String[fileArray.length];
languageLocale[0] = "Locale.ENGLISH";
languageLocale[1] = "Locale.FRENCH";
languageLocale[2] = "Locale.GERMAN";
languageLocale[3] = "Locale.ITALIAN";
languageLocale[4] = "Locale.SPANISH";
The short way:
String[] languageLocale = new String[("Locale.ENGLISH" , "Locale.FRENCH" , "Locale.GERMAN" , "Locale.ITALIAN" , "Locale.SPANISH")];
I need to input the Locale.(langauge) into a string so they can be called in the following:
File file = new File("\\LanguageGuessing5.0\\Learning\\");
File[] fileArray = file.listFiles();
ArrayList<String> words = new ArrayList<String>();
for (int i = 0; i < fileArray.length; i++) {
if (fileArray[i].isFile()) {
if (fileArray[i].isHidden()) {
continue;
} else {
String content = readUTF8File("\\LanguageGuessing5.0\\Learning\\"+fileArray[i].getName());
words = extractWords(content, languageLocale[i]);
outputWordsToUTF8File("\\LanguageGuessing5.0\\Model\\"+ fileArray[i].getName() + "out.txt", words);
}
} else if (fileArray[i].isDirectory()) {
System.out.println("Directory " + fileArray[i].getName());
}
}
The following method call:
words = extractWords(content, languageLocale[i]);
also presents the following error:
The method extractWords(String, Locale) in the type CleaningText(the class name) is not applicable for the arguments (String, String)
My understanding is that while the array argument is not a locale, the string holds the correct text to make it valid. I'm clearly incorrect, I'm hoping someone could explain how this works.
The input types of the methods are below for context:
public static String readUTF8File(String filePath)
public static ArrayList extractWords(String inputText, Locale currentLocale)
public static void outputWordsToUTF8File(String filePath, ArrayList wordList)
Many thanks in advance

ArrayList<String> in PDF from a new row

I want to send some survey in PDF from java, I tryed different methods. I use with StringBuffer and without, but always see text in PDF in one row.
public void writePdf(OutputStream outputStream) throws Exception {
Paragraph paragraph = new Paragraph();
Document document = new Document();
PdfWriter.getInstance(document, outputStream);
document.open();
document.addTitle("Survey PDF");
ArrayList nameArrays = new ArrayList();
StringBuffer sb = new StringBuffer();
int i = -1;
for (String properties : textService.getAnswer()) {
nameArrays.add(properties);
i++;
}
for (int a= 0; a<=i; a++){
System.out.println("nameArrays.get(a) -"+nameArrays.get(a));
sb.append(nameArrays.get(a));
}
paragraph.add(sb.toString());
document.add(paragraph);
document.close();
}
textService.getAnswer() this - ArrayList<String>
Could you please advise how to separate the text in order each new sentence will be starting from new row?
Now I see like this:
You forgot the newline character \n and your code seems a bit overcomplicated.
Try this:
StringBuffer sb = new StringBuffer();
for (String property : textService.getAnswer()) {
sb.append(property);
sb.append('\n');
}
What about:
nameArrays.add(properties+"\n");
You might be able to fix that by simply appending "\n" to the strings that you collecting in your list; but I think: that very much depends on the PDF library you are using.
You see, "newlines" or "paragraphs" are to a certain degree about formatting. It seems like a conceptual problem to add that "formatting" information to the data that you are processing.
Meaning: you might want to check if your library allows you to provide strings - and then have the library do the formatting for you!
In other words: instead of giving strings with newlines; you should check if you can keep using strings without newlines, but if there is way to have the PDF library add line breaks were appropriate.
Side note on code quality: you are using raw types:
ArrayList nameArrays = new ArrayList();
should better be
ArrayList<String> names = new ArrayList<>();
[ I also changed the name - there is no point in putting the type of a collection into the variable name! ]
This method is for save values in array list into a pdf document. In the mfilePath variable "/" in here you can give folder name. As a example "/example/".
and also for mFileName variable you can use name. I give the date and time that document will created. don't give static name other vice your values are overriding in same pdf.
private void savePDF()
{
com.itextpdf.text.Document mDoc = new com.itextpdf.text.Document();
String mFileName = new SimpleDateFormat("YYYY-MM-DD-HH-MM-SS", Locale.getDefault()).format(System.currentTimeMillis());
String mFilePath = Environment.getExternalStorageDirectory() + "/" + mFileName + ".pdf";
try
{
PdfWriter.getInstance(mDoc, new FileOutputStream(mFilePath));
mDoc.open();
for(int d = 0; d < g; d++)
{
String mtext = answers.get(d);
mDoc.add(new Paragraph(mtext));
}
mDoc.close();
}
catch (Exception e)
{
}
}

put/add is replacing all entires in a map or list

I am trying to convert a map: Map<String, Map<String, Map<String, Map<String, String>>>>to a Map<String, Settings>.
The Settings class contains all the possible map keys and will be set to true when looping through this particular key.
The problem is when in the deepest map, when adding to a global Map<String, Settings>, the Settings will be replaved with the last Settings for every entry.
Can someone help me find out where i do wrong?
public void loop(Map map, Settings settings){
List keys = new ArrayList(map.keySet());
if(map.get(keys.get(0)) instanceof Map){
//is a map, so continue loop + add to vorm
for(int i = 0; i < keys.size(); i++){
Settings tmp = settings;
String field = keys.get(i).toString();
Method method = null;
try {
//Set some booleans for key
method = tmp.getClass().getMethod(field, boolean.class);
method.invoke(tmp, true);
loop((Map) map.get(keys.get(i).toString()), tmp);
} catch (Exception e) {
e.printStackTrace();
}
}else{
for(int i = 0; i < keys.size(); i++) {
Settings tmp = settings;
String key = keys.get(i).toString();
String word = map.get(key).toString();
tmp.setWord(word);
Settings input = tmp;
settingsList.add(convert, input);//put into 2 arraylists
keyList.add(convert, woord);
convert++;
//vormen.put(word, tmp);//put into list
}
}
}
This method is called here:
public void convert(){
vormen = new HashMap();
settingsList = new ArrayList<>();
wordList = new ArrayList<>();
if(jsonMap.isEmpty()){
throw new NullPointerException("You are trying to convert a null map");
}else {
loop(jsonMap, new Settings());
}
}
Not every variable might be correctly named, i just renamed them.
Thanks for you help
EDIT: fixed, the temporary Settings that was put into the arrays was somehow being changed every time, acting like a pointer or something. I made a new Settings just before adding, and set the settings of tmp to that one. It works now.

Writing an Element object to file using java

I have a data of Element class. I'm trying to write its values to a file but I'm having trouble:
< Some process to acquire values into the variable "fieldData" >
// Prepare file output
FileWriter fstream = new FileWriter("C:/output.txt");
BufferedWriter out = new BufferedWriter(fstream);
Element field = fieldData.getElement(i);
out.write(field); // DOESN'T WORK: The method write(int) in the type BufferedWriter is not applicable for the arguments (Element)
out.write(field.getValueAsString()); // DOESN'T WORK: Cannot convert SEQUENCE to String
Any suggestions on how I should handle this case? In addition, what is the best way for me to see (i.e. print out to screen) the available static variables and methods associated with an object? Thx.
More code snippets to help debug:
private static final Name SECURITY_DATA = new Name("securityData");
private static final Name FIELD_DATA = new Name("fieldData");
Element securityDataArray = msg.getElement(SECURITY_DATA); // msg is a Bloomberg desktop API object
Element securityData = securityDataArray.getValueAsElement(0);
Element fieldData = securityData.getElement(FIELD_DATA);
Element field = fieldData.getElement(0)
out.write(field); // DOESN'T WORK: The method write(int) in the type BufferedWriter is not applicable for the arguments (Element)
out.write(field.getValueAsString()); // DOESN'T WORK: Cannot convert SEQUENCE to String
Turns out that this Bloomberg Prop data structure is long-winded to say the least:
private static final Name SECURITY_DATA = new Name("securityData");
private static final Name FIELD_DATA = new Name("fieldData");
Element securityDataArray = msg.getElement(SECURITY_DATA); // msg is a Bloomberg desktop API object
Element securityData = securityDataArray.getValueAsElement(0);
Element fieldData = securityData.getElement(FIELD_DATA);
Element field = fieldData.getElement(0);
/* the above codes were known at the time of the question */
/* below is what I was shown by a bloomberg representative */
Element bulkElement = field.getValueAsElement(0);
Element elem = bulkElement.getElement(0);
out.write(elem.name() + "\t" + elem.getValueAsString() + "\n");
whew...I don't think they try to make it easy! I'm also curious as to if there was a way that I could have figure this out by having Java print out the right method to use to trace down the data structure?
Element element = msg.GetElement("securityData");
for (int i = 0; i < element.NumValues; i++)
{
Element security = element.GetValueAsElement(i); //ie: DJI INDEX
Element fields = security.GetElement("fieldData");//ie: INDX_MEMBERS
for (int j = 0; j < fields.NumElements; j++)
{
Element field = fields.GetElement(j); //a list of members
for (int k = 0; k < field.NumValues; k++)
{
//print field.GetValueAsElement(k); //print members name
}
}
}
It sounds like you are trying to print the value of a input field element?
If so, then try:
out.write(field.getAttribute("value"));
Check out this one, for your second question:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html

Categories

Resources