Reputation: 3841
It is awfully often required to write repeatable pieces of code.
Consider the following example from Java
(although, it may not be the best example, but I hope you get the general idea...)
String X = rs.getString("X");
Where X
will have values: 'name'
,'surname'
... and 20
-30
other values.
(Another example would be an HTML
code and any other code - you need to create for X
)
The end result should be:
String name=rs.getString("name");
String surname=rs.getString("surname");
....
String whatever = rs.getString("whatever");
Here is another example with html
table and some scriplets
, in this case string to replicate would be <th>X</th>
and <td><%=myBean.getX()%></td>
the end result would be:
<table style="width:100%">
<tr>
<th>name</th>
<th>surname</th>
<th>..</th>
<th>whatever</th>
</tr>
<tr>
<td><%=myBean.getName()%></td>
<td><%=myBean.getSurname()%></td>
<td>..</td>
<td><%=myBean.getWhatever()%></td>
</tr>
</table>
So, apart form copy-pasting the above for 30
times and then editing, the the only 'clever' way I found to deal with this is to use python
, jinja2
library and write a small code generator.
But, in order to do that I had to install python
, install the library, create a template
, create a custom script
to read values from a text file
and then generate code for the values read.
I was wondering is there any easier way to achieve the above?
Any editor or plugin to support code generation?
I know that IDEs such as Netbeans, Eclipse can generate some code - like getters and setters ... etc, but it is not enough...
In a nutshell, I want to regenerate some lines of code by altering only specific parts ... The question is how to achieve that easily? (I know the hard way to do this) ..I am seeking for ideas...
Upvotes: 2
Views: 654
Reputation: 2460
You can do that with a lightweight code generator like Telosys :
In your case Telosys-CLI with a DSL model is probably the right choice, you'll just have to create your specific templates in Velocity language ( http://velocity.apache.org/ )
Upvotes: 2
Reputation: 3841
Probably I am looking for something that does not exist.
So, I'll just post my 'hard way' of achieving, what I have described in my question (in hope that this would be useful for somebody - sometime).
Here I will preset a small code generator I am using to generate java, html, jsp, xsd and other codes.
I am using Python27 and Jinja2-2.7.2
My Files:
InputData.txt
:This is field list
field1:field1 description
field2:field2 description
field3:field3 description
field4:field4 description
name:first name of the person
surname:last name of the person
whatever:whatever you need
CodeGenerator.py
import jinja2
import codecs
templateLoader = jinja2.FileSystemLoader( searchpath="." )
templateEnv = jinja2.Environment( loader=templateLoader )
TEMPLATE_FILE = "CodeGenerator.jinja"
template = templateEnv.get_template( TEMPLATE_FILE )
COLUMNS = [tuple(line.split(':')) for line in codecs.open( "InputData.txt", "r", "utf-8" )]
COLUMNS = map(lambda s: (s[0],(s[0].strip().title(),s[1].strip())), COLUMNS)
#title() copy of the string in which first characters of all the words are capitalized.
#strip() copy of the string, all chars have been stripped from the beginning and the end
#lambda s --> (field1,(Field1,field1 description))
#ignore the first line
COLUMNS.pop(0)
#add variables to work with
templateVars = { "table" : "MyTableName",
"description" : "A simple code generator",
"columns" : COLUMNS
}
outputText = template.render( templateVars )
f = open('Generated.txt', 'w')
outputText = outputText.encode('utf-8')
f.write(outputText)
f.close()
print outputText
CodeGenerator.jinja
//------------------model------------------------
//Generated code for model
import java.io.Serializable;
public class {{table|capitalize}}_Model implements Serializable{
{%for columnName,columnTitle in columns%}
private String {{columnName|lower}};{%endfor%}
{% for columnName,columnTitle in columns %}
public void set{{columnName|capitalize}}(String {{columnName|lower}}){
this.{{columnName|lower}}={{columnName|lower}};
}
public String get{{columnName|capitalize}}(){
return this.{{columnName|lower}};
}
{% endfor %}
public {{table|capitalize}}_Model({% for columnName,columnTitle in columns %}String {{columnName|lower}}{% if not loop.last %},{% endif %}{% endfor %}){
{% for columnName,columnTitle in columns %}
this.{{columnName|lower}}={{columnName|lower}}; {% endfor %}
}
public String toString(){
return {% for columnName,columnTitle in columns %}"{{columnName|lower}}:" + this.{{columnName|lower}}{% if not loop.last %}+{% endif %}{% endfor %};
}
}
//------------------model------------------------
//-----------------getStrings--------------------
{% for columnName,columnTitle in columns %}
String {{columnName}}=rs.getString("{{columnName}}");
{% endfor %}
//----------------------------------------------
//------------------jsp example-----------------
{% for columnName,columnTitle in columns %}
<s:label cssStyle ="margin-top:5px;color:blue;" value="{{columnTitle[1]}} :" id="{{columnName}}_label"/>
<s:textfield label="{{columnTitle[1]}}" name="myBean.{{columnName}}" />
{% endfor %}
//------------------jsp example-----------------
Upvotes: 1
Reputation: 753
In such scenarios, the best thing you could do is to use a constant array together with a HashMap. The constant array will hold keynames for the hashmap whereas the hashmap will also hold the value for each one.
For instance:
String[] keys = {"name", "surname", "whatever" };
HashMap<String, String> elements = new HashMap<String, String>();
for (String key : keys)
{
elements.put(key, rs.getString(key));
}
You just have to be careful that all the elements are from the same type. If they are not, you will have to either store them as Objects and then cast them.
EDIT: for using in a Scriptlet, a good idea would be:
<tr>
<% for (String key : keys)
{
%>
<td><%= elements.get(key)%></td>
<% } %>
</tr>
Upvotes: 0
Reputation: 811
If I understand your problem correctly, you have a ResultSet
with a lot of columns. And you do not want to get them one by one.
It is possible to get all the columns from a ResultSet
the following way:
ResultSetMetaData metaData = resultSet.getMetaData();
for (int columnIndex = 1; columnIndex <= metaData.getColumnCount(); columnIndex++) {
String columnName = metaData.getColumnName(columnIndex);
String value = resultSet.getString(columnIndex);
}
Granted all the values will b e represented as strings in this example, but you can determine the type of the column also by using the same metaData
object. Read more about it in the documentation: https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html
Upvotes: -1
Reputation: 19
In IntelliJ we have "Live Template" feature that you use to generate part of the code.
For example, when you type "sout" , IntelliJ suggests "System.out.println".
When you type "main" , Eclipse suggests "public static void main(String[] args)"
You can create something like that for pieces of code that are very commom.
Upvotes: -1