Display hashmap key in jstl - jstl

I have tried so many different ways to display this contents of the hashmap based on a key and i would like to be told if im doing it the wrong way please?
session.setAttribute("AvailableLessons", availableLessons.getLessons());
<c:forEach var="temp" items="${sessionScope.AvailableLessons}">
<tbody>
<tr>
<form action="" method="POST">
<td>
<c:out value="${temp['description']}"/>
</td>
<td>
Bean code:
public class LessonTimetable implements Serializable {
private Connection connection = null;
private ResultSet rs = null;
private PreparedStatement st = null;
private Map lessons = new HashMap<String, List<Lesson>>();
private DataSource ds = null;
public Lesson less;
public LessonTimetable() {
// You don't need to make any changes to the try/catch code below
try {
// Obtain our environment naming context
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// Look up our data source
ds = (DataSource) envCtx.lookup("jdbc/LessonDatabase");//change to LessonDatabase..will also have to setup credentials for my virtualmin server account.
} catch (Exception e) {
System.out.println("Exception message is " + e.getMessage());
}
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
try {
if (connection != null) {
// TODO instantiate and populate the 'lessons' HashMap by selecting the relevant infromation from the database
List<String> putDescriptions = new ArrayList<String>();
List<String> putDates = new ArrayList<String>();
List<String> putStartTime = new ArrayList<String>();
List<Integer> Level = new ArrayList<Integer>();
List<String> LessonID = new ArrayList<String>();
List<String> endTime = new ArrayList<String>();
String query = String.format("SELECT description,level,startDateTime,endDateTime,lessonid FROM LESSONS");
st = connection.prepareStatement(query);
rs = st.executeQuery();
connection.setAutoCommit(false);
st.setFetchSize(0);
while (rs.next()) {
String getDescription = rs.getString("description");
int level = rs.getInt("level");
Timestamp startDate = rs.getTimestamp("startDateTime");
Timestamp endDate = rs.getTimestamp("endDateTime");
String LessonId = rs.getString("lessonid");
this.less = new Lesson(getDescription, startDate, endDate, level, LessonId);
putDescriptions.add(less.description);
putStartTime.add(less.startTime);
endTime.add(less.endTime);
List list = Arrays.asList(less.date.split("2010"));
for (int i = 0; i < list.size(); i++) {
putDates.add(list.get(i).toString());
Level.add(less.level);
LessonID.add(less.ID);
this.lessons.put("description", putDescriptions);
this.lessons.put("StartDate", putDates);
this.lessons.put("StartTime", putStartTime);
this.lessons.put("EndTime", endTime);
this.lessons.put("Level", Level);
this.lessons.put("LessonID", LessonID);

If I understand correctly, availableLessons.getLessons()returns a Map, containing "description" as a key.
Your code starts with session.setAttribute("AvailableLessons", availableLessons.getLessons());. So the attribute AvailableLessonscontains a Map.
So, all you need to access the value associated to the key "description" in that Map is
${AvailableLessons['description']}
No need for a loop, just like in Java you would only need
availableLessons.get("description")
to access this value, without any need for a loop.

Related

Spring Boot and Hibernate Dynamic Id Generator for invoice Number

I am working on Spring boot Application with hibernate to create simple invoice.
I want to generate invoice number through hibernate in the following format
as below
YEAR/MONTH/Number(Will Increase)
The above sequence is dependent on invoice date.
Month and year values do change based on the current Date.
Once the year completed, let say after the completion of one financial
year the sequence again start from the beginning, like month/Year/number.
I have tried to Sequence Generator , table Generator . My Code snippet is as below :
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "year_gen")
#GenericGenerator(name = "year_gen", strategy = "com.example.generator.CustomGenerator")
#Column(name = "invoice_no")
private String invoiceno;
But I am not getting any idea that how to make it dependable on Invoice Date.
My Generator is below :
public class CustomGenerator implements IdentifierGenerator {
#Override
public Serializable generate(SharedSessionContractImplementor sessionImpl, Object data)
throws HibernateException {
Serializable result = null;
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
String prefix = "";
DateTimeFormatter newPattern = DateTimeFormatter.ofPattern("yyyyMM");
LocalDate ldObj = LocalDate.now();
String yyyymm = newPattern.format(ldObj).toString();
prefix = "INV/"+yyyymm+"/";
connection = sessionImpl.connection();
statement = connection.createStatement();
try {
resultSet = statement.executeQuery("select max(id)+1 from invoice");
} catch(Exception ex) {
}
if(resultSet.next()) {
int nextValue = resultSet.getInt(1);
String suffix = String.format("%05d", nextValue + 1);
result = prefix.concat(suffix);
System.out.println("Custom generated Sequence value : "+result);
} else
{
int nextValue = 1;
String suffix = String.format("%05d", nextValue + 1);
result = prefix.concat(suffix);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
}

why does my return statement return a null result?

I am trying to connect to a distant machine and display some files from a specific directory.
The problem is when I test my function it returns a null result and what I want to do is to display file names.
Here is my code:
#Service
public class SftpClientImpl implements SftpClient {
private LsEntry entry;
#Override
public LsEntry connectToServer() {
String SFTPHOST = "xxxxx";
int SFTPPORT = 22;
String SFTPUSER = "xxx";
String SFTPPASS = "xxxxx";
String SFTPWORKINGDIR = "/dir/dir2/dir3";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
try{
JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER,SFTPHOST,SFTPPORT);
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
System.out.println("Starting the session ..");
channelSftp = (ChannelSftp)channel;
channelSftp.cd(SFTPWORKINGDIR);
Vector filelist = channelSftp.ls(SFTPWORKINGDIR);
for(int i=0; i<filelist.size();i++){
LsEntry entry = (LsEntry) filelist.get(i);
System.out.println(entry.getFilename());
}
while(session != null){
System.out.println("Killing the session");
session.disconnect();
System.exit(0);
}
}catch(Exception ex){
ex.printStackTrace();
}
return entry;
}
}
and:
#GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<LsEntry> getDirectories() {
LsEntry entry = sftpClient.connectToServer();
return new ResponseEntity<>(entry, HttpStatus.OK);
}
Any idea why this is not working?
entry is null as it's value is only contained within the for loop, and is actually declared twice (once with private class scope, once with local scope within the for loop).
What I suggest is to correct your variable declaration and test the connection and filename printing. If it still doesn't work, try it within a known working spring endpoint. If it prints your directory as expected than move to its own endpoint and try again. In doing this it'll help narrow down the scope of your issue.
I've used the below code to connect to and print file names for the past few years and is heavily based on the example code provided by JSCH back then:
JSch jsch = new JSch();
Session session;
session = jsch.getSession(username, hostname, port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(password);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
//List our files within the directory
Vector vv = sftpChannel.ls(srcDir);
if (vv != null) {
LOGGER.debug("We have a file listing!");
for (int ii = 0; ii < vv.size(); ii++) {
Object obj = vv.elementAt(ii);
if (obj instanceof ChannelSftp.LsEntry) {
LOGGER.debug("[" + ((ChannelSftp.LsEntry) obj).getFilename() + "]");
if (ii < 1) { // empty directory contains entries for . and ..
continue;
}
String filename = ((ChannelSftp.LsEntry) obj).getFilename();
filenames.add(filename);
LOGGER.debug("filename is: {}", filename);
....
this is how i solved my problem :)
I corrected my variable declaration and it worked nicely, like you told me to :) thanks
#Override
public LsEntry connectToServer() {
String HOST = "xxxxx";
int PORT = 22;
String USER = "xxx";
String PASS = "xxxxx";
String DIR = "/dir/dir2/dir3";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
// LsEntry declaration
LsEntry entry = null;
try {
JSch jsch = new JSch();
session = jsch.getSession(USER, HOST, PORT);
session.setPassword(PASS);
// the rest of the code
//....
//...
for (int i = 0; i < filelist.size(); i++) {
//cast
entry = (LsEntry) filelist.get(i);
System.out.println(((LsEntry) entry).getFilename());
}
while (session != null) {
System.out.println("Killing the session");
session.disconnect();
System.exit(0);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return (LsEntry) entry;
}

how to transfer flowfiles one by one using a custom processor in NIFI

I'm programming a custom processor in Nifi v 1.3
The processor executes an SQL query read from the resultset and transforms every row to json document and stores it into an ArrayList, finally it transfers every 1000 document (fetchSize param) to a flowfile, this work for me, but it sends all flowFiles at once.
What I want is for it to transfer each flowfile independently when I call transferFlowFile method without waiting for the end of the onTrigger method to transfer everything at once.
here the code :
public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
FlowFile fileToProcess = null;
if (context.hasIncomingConnection()) {
fileToProcess = session.get();
if (fileToProcess == null && context.hasNonLoopConnection()) {
return;
}
}
final ResultSet resultSet = st.executeQuery();
final ResultSetMetaData meta = resultSet.getMetaData();
final int nrOfColumns = meta.getColumnCount();
List<Map<String, Object>> documentList = new ArrayList<>();
while (resultSet.next()) {
final AtomicLong nrOfRows = new AtomicLong(0L);
cpt++;
Map<String, Object> item = new HashMap<>();
for (int i = 1; i <= nrOfColumns; i++) {
int javaSqlType = meta.getColumnType(i);
String nameOrLabel = StringUtils.isNotEmpty(meta.getColumnLabel(i)) ? meta.getColumnLabel(i)
: meta.getColumnName(i);
Object value = null;
value = resultSet.getObject(i);
if (value != null) {
item.put(nameOrLabel, value.toString());
}
}
Document document = new Document(item);
documentList.add(document);
if (fetchSize!=0 && cpt % fetchSize == 0) {
FlowFile flowFile = session.create();
transferFlowFile(flowFile, session, documentList, fileToProcess, nrOfRows, stopWatch);
}
}
if (!documentList.isEmpty()) {
final AtomicLong nrOfRows = new AtomicLong(0L);
FlowFile flowFile = session.create();
transferFlowFile(flowFile, session, documentList, fileToProcess, nrOfRows, stopWatch);
}
}
public void transferFlowFile(FlowFile flowFile, ProcessSession session, List<Map<String, Object>> documentList,
FlowFile fileToProcess, AtomicLong nrOfRows, StopWatch stopWatch) {
flowFile = session.write(flowFile, out -> {
ObjectMapper mapper = new ObjectMapper();
IOUtils.write(mapper.writeValueAsBytes(documentList), out);
});
documentList.clear();
flowFile = session.putAttribute(flowFile, CoreAttributes.MIME_TYPE.key(), "application/json");
session.getProvenanceReporter().modifyContent(flowFile, "Retrieved " + nrOfRows.get() + " rows",
stopWatch.getElapsed(TimeUnit.MILLISECONDS));
session.transfer(flowFile, REL_SUCCESS);
}
Call session.commit() after
session.transfer(flowFile, REL_SUCCESS)
The any flows files created since the last commit, or since the beginning if there was never a commit, will be transferred when the session is committed.

Added DataColumns not being saving in Access Database

I would like to write code to add a DataColumn to a DataTable, but when I save the DataTable, it does not include the new DataColumn.
It saves any new DataRows I add, but not the DataColumns.
Can somebody please tell me what I am doing wrong?
public partial class Form1 : Form
{
MyDatabase DB;
DataTable Products;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DB = new MyDatabase();
DB.Open(#"C:\Users\Grant\Documents\Database.accdb");
Products = DB.GetTable("Products");
AddColumn();
AddRow();
DB.Save(Products);
}
private void AddColumn()
{
DataColumn Column = new DataColumn();
Column.DataType = Type.GetType("System.String");
Column.ColumnName = "TestColumn";
Products.Columns.Add(Column);
}
private void AddRow()
{
DataRow Row;
Row = Products.Rows.Add(1, "B", "C");
}
}
class MyDatabase
{
// The following program has to be installed on the computer
// http://www.microsoft.com/downloads/en/details.aspx?familyid=7554F536-8C28-4598-9B72-EF94E038C891&displaylang=en
private String provider = "Microsoft.ACE.OLEDB.12.0";
private String source;
private OleDbConnection connection;
private String connectionString;
private DataSet dataSet = new DataSet();
private OleDbDataAdapter adapter;
private OleDbCommandBuilder commandBuilder;
public String Provider
{
get { return provider; }
set { provider = value; }
}
public String Source
{
get { return Source; }
set { source = value; }
}
public void Open(String Filename)
{
connectionString = #"Provider=" + provider + #";Data Source=" + Filename;
connection = new OleDbConnection(connectionString);
connection.Open();
adapter = new OleDbDataAdapter();
}
public void BuildStrings()
{
commandBuilder = new OleDbCommandBuilder(adapter);
adapter.UpdateCommand = commandBuilder.GetUpdateCommand();
adapter.InsertCommand = commandBuilder.GetInsertCommand();
adapter.DeleteCommand = commandBuilder.GetDeleteCommand();
}
public DataTable GetTable(String TableName)
{
adapter.SelectCommand = new OleDbCommand("SELECT * From " + TableName, connection);
BuildStrings();
adapter.Fill(dataSet, TableName);
return dataSet.Tables[TableName];
}
public void Save(DataTable Table)
{
adapter.Update(Table);
adapter.Update(dataSet, "Products");
}
}
Got an answer from a different forum.
You can not add new column/field to database table using dataset or datatable you might need to use "ALTER TABLE" with ADO.NET commands. Check below links
How Can I Insert New Column Into A Database Table Using SqlDataAdapter and DataTable?[^]
adding a column to a SQL table in VB using ADO.NET commands[^]

JdbcTemplate delete syntax

Can someone point out any mistake in my following code of Spring Jdbc Template?
When I click delete, the record is not getting deleted and there are no errors showing.
public void delete(String id) {
logger.debug("Deleting existing person");
// Prepare our SQL statement using Unnamed Parameters style
String query = "delete from person where id = ?";
// Assign values to parameters
Object[] person = new Object[] {id};
// Delete
jdbcTemplate.update(query, person);
}
Here is an example. Pay attention:
Integer id
public boolean delete(Integer id){
String sql = "DELETE FROM organization WHERE id = ?";
Object[] args = new Object[] {id};
return jdbcTemplate.update(sql, args) == 1;
}
#Override
public String deleteXXById(String id) {
String sql = "DELETE FROM VENUE WHERE id =:id?";
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("id", id);
Object[] args = new Object[] {id};
int update = jdbcTemplate.update(sql, paramMap);
String updatecount = "Failed";
if (update == 0) {
updatecount = "Failed";
} else {
updatecount = "SUCCESS";
}
return updatecount;
}

Resources