Drools decision table - rules not matching - spring-boot

I have a hello-world type spring/drools setup. The issue is no rules fire when in theory they should.
Decision Table:
Console output - server startup:
package com.example.drools;
//generated from Decision Table
import com.example.drools.TestRules;
// rule values at B9, header at B4
rule "_9"
when
$test:TestRules(number1 == 10)
then
$test.add("10");
end
Drools Config:
#Configuration
public class DroolsConfiguration
{
private final static String VALIDATION_RULES = "validation-rules.xls";
#Bean
public KieContainer validationRulesKieContainer() {
KieServices kieServices = KieServices.Factory.get();
Resource rules = ResourceFactory.newClassPathResource(VALIDATION_RULES);
compileXlsToDrl(rules);
KieFileSystem kieFileSystem = kieServices.newKieFileSystem().write(rules);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
KieBuilder builder = kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
private static void compileXlsToDrl(Resource resource) {
try {
InputStream is = resource.getInputStream();
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(is, InputType.XLS);
System.out.println(drl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Service:
#Service
public class ValidationRulesEngine
{
#Autowired
#Qualifier("validationRulesKieContainer")
private KieContainer validationKieContainer;
public void validate() {
KieSession kieSession = validationKieContainer.newKieSession();
kieSession.addEventListener(new DebugAgendaEventListener());
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
TestRules tr = new TestRules(10, 20, 30);
kieSession.insert(tr);
int noOfRulesFired = kieSession.fireAllRules();
System.out.println("noOfRulesFired: " + noOfRulesFired);
System.out.println(tr);
System.out.println(tr.getRule());
}
}
TestRule - Fact:
public class TestRules
{
public int number1;
public int number2;
public int number3;
public List<String> rules = new ArrayList<String>();
public TestRules() {}
public TestRules(int number1, int number2, int number3)
{
super();
this.number1 = number1;
this.number2 = number2;
this.number3 = number3;
}
public void add(String rule) {
rules.add(rule);
}
public String getRule() {
return this.rules.size() > 0 ? this.rules.get(0) : "";
}
#Override
public String toString()
{
return "TestRules [number1=" + number1 + ", number2=" + number2 + ", number3=" + number3 + ", rules=" +
rules.stream().map(s -> s.toString()).collect(Collectors.joining(",")) + "]";
}
}
Console output - result:
2021-07-20 17:02:27.549 ERROR 20212 --- [nio-9016-exec-1] c.g.i.e.p.c.OfficeController : --> Rules Engine
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:1:1539328290:1539328290:1:DEFAULT:NON_TRAIT:com.example.drools.TestRules:TestRules [number1=10, number2=20, number3=30, rules=]], getObject()=TestRules [number1=10, number2=20, number3=30, rules=], getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:1:1539328290:1539328290:1:DEFAULT:NON_TRAIT:com.example.drools.TestRules:TestRules [number1=10, number2=20, number3=30, rules=]], leftTuple=null, originOffset=-1, propagationNumber=2, rule=null, type=INSERTION]]
noOfRulesFired: 0
TestRules [number1=10, number2=20, number3=30, rules=]
2021-07-20 17:02:28.454 ERROR 20212 --- [nio-9016-exec-1] c.g.i.e.p.c.OfficeController : <-- Rules Engine
What am I missing?

This is no good:
$test:TestRules($test.number1 == 10, $test.number2 == 20)
You can't refer to $test before you declare it. The correct syntax is:
$test: TestRules( number1 == 10, number2 == 20 )
Fix your decision table from $test.number1 == $param to instead be number1 == $param. (And do the same for number2 adjacent.)
The rest looks fine, though I would suggest using a try-with-resources instead of a try-catch in your XLSX parsing method.

Related

How to write a junit test case for private methods that are inside an if condition?

This is my service class, It has public method getFilesFromDirAndUploadtoHost() and inside that i have a reattempt() inside an if condition. I need to cover more codes by junit. What will be the modified test class, test class i mentioned below.*
#Service
public class FileTransferServiceImpl {
#Override
public Boolean getFilesFromDirAndUploadtoHost() throws SftpException {
List<String> files = Stream.of(new File(sourcePath).listFiles()).filter(file -> !file.isDirectory())
.map(File::getName).filter(file -> !file.endsWith("zip")).collect(Collectors.toList());
if(files.isEmpty()){
logger.info("No Files found to transfer");
return true;
}
ChannelSftp channelSftp = createChannelSftp();
Boolean result = false;
Integer attemptNo = 0;
Date date = new Date();
SimpleDateFormat formatDate = new SimpleDateFormat("dd-MM-yyyy HH mm ss z");
formatDate.setTimeZone(TimeZone.getTimeZone("IST"));
String dirName = formatDate.format(date);
if (channelSftp != null) {
// Create new folder in target
try {
channelSftp.mkdir("/" + dirName);
} catch (SftpException e) {
logger.error("Directory creation unsuccessful", e);
}
// Initial Attempt
List<ProcessFile> processFiles = copyFilestoTarget(channelSftp, files, attemptNo, dirName);
List<ProcessFile> failedFiles = processFiles.stream().filter(processFile -> !processFile.getSuccessfulYN())
.collect(Collectors.toList());
// If any Failed files found set to retry
if (!failedFiles.isEmpty()) {
reattempt(channelSftp, failedFiles, attemptNo, processFiles, dirName);
}
disconnectChannelSftp(channelSftp);
// populaate Process Run
populateAndSaveProcessRun(processFiles, files, dirName);
result = true;
}
return result;
}
private List<ProcessFile> copyFilestoTarget(ChannelSftp channelSftp, List<String> files, Integer attempNo,
String dirName) {
List<ProcessFile> processFiles = new ArrayList<>();
for (String fileName : files) {
try {
if (!channelSftp.isConnected()) {
channelSftp = recreateChannelSftp();
}
channelSftp.put(sourcePath + "/" + fileName, targetPath + "/" + dirName);
processFiles.add(populateProcessFiles(fileName, attempNo, dirName, true));
} catch (JSchException e) {
logger.error("Reconnection failed attempt No: " + attempNo);
processFiles.add(populateProcessFiles(fileName, attempNo, dirName, false));
} catch (SftpException e) {
logger.error("File : " + fileName + " Transfer Failed Attempt No: " + attempNo);
processFiles.add(populateProcessFiles(fileName, attempNo, dirName, false));
}
}
return processFiles;
}
private void reattempt(ChannelSftp channelSftp, List<ProcessFile> failedFiles, Integer attemptNo,
List<ProcessFile> processFiles, String dirName) {
attemptNo = 1;
List<ProcessFile> newFailedFile = failedFiles;
while (attemptNo <= 3) {
newFailedFile = copyFilestoTarget(channelSftp,
newFailedFile.stream().filter(processFile -> !processFile.getSuccessfulYN())
.map(processFile -> processFile.getFileName()).collect(Collectors.toList()),
attemptNo, dirName);
processFiles.addAll(newFailedFile);
if (newFailedFile.stream().filter(processFile -> !processFile.getSuccessfulYN())
.collect(Collectors.toList()).isEmpty()) {
attemptNo = 4;
} else {
attemptNo++;
}
}
}
}
This is my test class what i shoule modify here so that i can cover more lines. Here i am not sure how to do that. If any one can help it will be great.
#ExtendWith(MockitoExtension.class)
public class FileTransferServiceTest {
#InjectMocks
private FileTransferServiceImpl fileTransferService = new FileTransferServiceImpl();
#Mock
private ProcessFileService processFileService;
#BeforeEach
public void beforeClass() {
ReflectionTestUtils.setField(fileTransferService, "sourcePath", "F:\\Sample-sftp prjt\\needToTransfer");
ReflectionTestUtils.setField(fileTransferService, "host", "SDC-CDPGP01-test.com.au");
ReflectionTestUtils.setField(fileTransferService, "port", 2222);
ReflectionTestUtils.setField(fileTransferService, "username", "tester");
ReflectionTestUtils.setField(fileTransferService, "password", "password");
ReflectionTestUtils.setField(fileTransferService, "sessionTimeout", 15000);
ReflectionTestUtils.setField(fileTransferService, "channelTimeout", 15000);
ReflectionTestUtils.setField(fileTransferService, "targetPath", "/");
}
#Test
void uploadToAemo() throws SftpException {
assertNotNull(fileTransferService.getFilesFromDirAndUploadtoHost());
}
}

How to export huge result set from database into several csv files and zip them on the fly?

I need to create a REST controller which extracts data from a database and write it into CSV files that will ultimately be zipped together. Each CSV file should contain exactly 10 lines. Eventually all CSV files should be zipped into a one zip file. I want everything to happen on the fly, meaning - saving files to a temporary location on the disk is not an option. Can someone provide me with an example?
I found a very nice code to export huge amount of rows from database into several csv files and zip it.
I think this is a nice code that can assist alot of developers.
I have tested the solution and you can find the entire example at : https://github.com/idaamit/stream-from-db/tree/master
The conroller is :
#GetMapping(value = "/employees/{employeeId}/cars") #ResponseStatus(HttpStatus.OK) public ResponseEntity<StreamingResponseBody> getEmployeeCars(#PathVariable int employeeId) {
log.info("Going to export cars for employee {}", employeeId);
String zipFileName = "Cars Of Employee - " + employeeId;
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, "application/zip")
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + zipFileName + ".zip")
.body(
employee.getCars(dataSource, employeeId));
The employee class, first checks if we need to prepare more than one csv or not :
public class Employee {
public StreamingResponseBody getCars(BasicDataSource dataSource, int employeeId) {
StreamingResponseBody streamingResponseBody = new StreamingResponseBody() {
#Override
public void writeTo(OutputStream outputStream) throws IOException {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sqlQuery = "SELECT [Id], [employeeId], [type], [text1] " +
"FROM Cars " +
"WHERE EmployeeID=? ";
PreparedStatementSetter preparedStatementSetter = new PreparedStatementSetter() {
public void setValues(PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setInt(1, employeeId);
}
};
StreamingZipResultSetExtractor zipExtractor = new StreamingZipResultSetExtractor(outputStream, employeeId, isMoreThanOneFile(jdbcTemplate, employeeId));
Integer numberOfInteractionsSent = jdbcTemplate.query(sqlQuery, preparedStatementSetter, zipExtractor);
}
};
return streamingResponseBody;
}
private boolean isMoreThanOneFile(JdbcTemplate jdbcTemplate, int employeeId) {
Integer numberOfCars = getCount(jdbcTemplate, employeeId);
return numberOfCars >= StreamingZipResultSetExtractor.MAX_ROWS_IN_CSV;
}
private Integer getCount(JdbcTemplate jdbcTemplate, int employeeId) {
String sqlQuery = "SELECT count([Id]) " +
"FROM Cars " +
"WHERE EmployeeID=? ";
return jdbcTemplate.queryForObject(sqlQuery, new Object[] { employeeId }, Integer.class);
}
}
This class StreamingZipResultSetExtractor is responsible to split the csv streaming data into several files and zip it.
#Slf4j
public class StreamingZipResultSetExtractor implements ResultSetExtractor<Integer> {
private final static int CHUNK_SIZE = 100000;
public final static int MAX_ROWS_IN_CSV = 10;
private OutputStream outputStream;
private int employeeId;
private StreamingCsvResultSetExtractor streamingCsvResultSetExtractor;
private boolean isInteractionCountExceedsLimit;
private int fileCount = 0;
public StreamingZipResultSetExtractor(OutputStream outputStream, int employeeId, boolean isInteractionCountExceedsLimit) {
this.outputStream = outputStream;
this.employeeId = employeeId;
this.streamingCsvResultSetExtractor = new StreamingCsvResultSetExtractor(employeeId);
this.isInteractionCountExceedsLimit = isInteractionCountExceedsLimit;
}
#Override
#SneakyThrows
public Integer extractData(ResultSet resultSet) throws DataAccessException {
log.info("Creating thread to extract data as zip file for employeeId {}", employeeId);
int lineCount = 1; //+1 for header row
try (PipedOutputStream internalOutputStream = streamingCsvResultSetExtractor.extractData(resultSet);
PipedInputStream InputStream = new PipedInputStream(internalOutputStream);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(InputStream))) {
String currentLine;
String header = bufferedReader.readLine() + "\n";
try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
createFile(employeeId, zipOutputStream, header);
while ((currentLine = bufferedReader.readLine()) != null) {
if (lineCount % MAX_ROWS_IN_CSV == 0) {
zipOutputStream.closeEntry();
createFile(employeeId, zipOutputStream, header);
lineCount++;
}
lineCount++;
currentLine += "\n";
zipOutputStream.write(currentLine.getBytes());
if (lineCount % CHUNK_SIZE == 0) {
zipOutputStream.flush();
}
}
}
} catch (IOException e) {
log.error("Task {} could not zip search results", employeeId, e);
}
log.info("Finished zipping all lines to {} file\\s - total of {} lines of data for task {}", fileCount, lineCount - fileCount, employeeId);
return lineCount;
}
private void createFile(int employeeId, ZipOutputStream zipOutputStream, String header) {
String fileName = "Cars for Employee - " + employeeId;
if (isInteractionCountExceedsLimit) {
fileCount++;
fileName += " Part " + fileCount;
}
try {
zipOutputStream.putNextEntry(new ZipEntry(fileName + ".csv"));
zipOutputStream.write(header.getBytes());
} catch (IOException e) {
log.error("Could not create new zip entry for task {} ", employeeId, e);
}
}
}
The class StreamingCsvResultSetExtractor is responsible for transfer the data from the resultset into csv file. There is more work to do to handle special character set which are problematic in csv cell.
#Slf4j
public class StreamingCsvResultSetExtractor implements ResultSetExtractor<PipedOutputStream> {
private final static int CHUNK_SIZE = 100000;
private PipedOutputStream pipedOutputStream;
private final int employeeId;
public StreamingCsvResultSetExtractor(int employeeId) {
this.employeeId = employeeId;
}
#SneakyThrows
#Override
public PipedOutputStream extractData(ResultSet resultSet) throws DataAccessException {
log.info("Creating thread to extract data as csv and save to file for task {}", employeeId);
this.pipedOutputStream = new PipedOutputStream();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
prepareCsv(resultSet);
});
return pipedOutputStream;
}
#SneakyThrows
private Integer prepareCsv(ResultSet resultSet) {
int interactionsSent = 1;
log.info("starting to extract data to csv lines");
streamHeaders(resultSet.getMetaData());
StringBuilder csvRowBuilder = new StringBuilder();
try {
int columnCount = resultSet.getMetaData().getColumnCount();
while (resultSet.next()) {
for (int i = 1; i < columnCount + 1; i++) {
if(resultSet.getString(i) != null && resultSet.getString(i).contains(",")){
String strToAppend = "\"" + resultSet.getString(i) + "\"";
csvRowBuilder.append(strToAppend);
} else {
csvRowBuilder.append(resultSet.getString(i));
}
csvRowBuilder.append(",");
}
int rowLength = csvRowBuilder.length();
csvRowBuilder.replace(rowLength - 1, rowLength, "\n");
pipedOutputStream.write(csvRowBuilder.toString().getBytes());
interactionsSent++;
csvRowBuilder.setLength(0);
if (interactionsSent % CHUNK_SIZE == 0) {
pipedOutputStream.flush();
}
}
} finally {
pipedOutputStream.flush();
pipedOutputStream.close();
}
log.debug("Created all csv lines for Task {} - total of {} rows", employeeId, interactionsSent);
return interactionsSent;
}
#SneakyThrows
private void streamHeaders(ResultSetMetaData resultSetMetaData) {
StringBuilder headersCsvBuilder = new StringBuilder();
for (int i = 1; i < resultSetMetaData.getColumnCount() + 1; i++) {
headersCsvBuilder.append(resultSetMetaData.getColumnLabel(i)).append(",");
}
int rowLength = headersCsvBuilder.length();
headersCsvBuilder.replace(rowLength - 1, rowLength, "\n");
pipedOutputStream.write(headersCsvBuilder.toString().getBytes());
}
}
In order to test this, you need to execute http://localhost:8080/stream-demo/employees/3/cars

Invoke lambda function handler java

I have a lambda function which has a handler which inturn has multiple routers. Each router corresponds to an API.
I have created a lambda client in java and need to call those APIs. To call these APIs, I need to invoke the handler and pass a payload to the client along with it. Can you guys help me with the syntax for invoking the handler and passing the payload.
If I understand your question correctly I first created a Lambda that looked like:
public class SampleHandler implements RequestStreamHandler {
private static final Logger logger = LogManager.getLogger(SampleHandler.class);
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
logger.info("handlingRequest");
LambdaLogger lambdaLogger = context.getLogger();
ObjectMapper objectMapper = new ObjectMapper();
String inputString = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining("\n"));
JsonNode jsonNode = objectMapper.readTree(inputString);
String route = jsonNode.get("route").asText();
RouterResult routerResult = new RouterResult();
switch( route ) {
case "requestTypeA":
RequestTypeA requestTypeA = objectMapper.readValue(inputString, RequestTypeA.class);
routerResult.setResult(handleRequestTypeA(requestTypeA));
break;
case "requestTypeB":
RequestTypeB requestTypeB = objectMapper.readValue(inputString, RequestTypeB.class);
routerResult.setResult(handleRequestTypeB(requestTypeB));
break;
default:
logger.error( "don't know how to handle route of type \"" + route + "\n" );
routerResult.setResult("error");
}
outputStream.write(objectMapper.writeValueAsString(routerResult).getBytes(StandardCharsets.UTF_8));
logger.info("done with run, remaining time in ms is " + context.getRemainingTimeInMillis() );
}
private String handleRequestTypeA(RequestTypeA requestTypeA) {
logger.info("handling requestTypeA, requestTypeA.requestA is " + requestTypeA.getRequestA() );
return "handled requestTypeA";
}
private String handleRequestTypeB(RequestTypeB requestTypeB) {
logger.info("handling requestTypeB, requestTypeB.requestB is " + requestTypeB.getRequestB() );
return "handled requestTypeB";
}
}
with RouterRequest.java:
public class RouterRequest {
protected String route;
public String getRoute() {
return route;
}
}
and RequestTypeA.java:
public class RequestTypeA extends RouterRequest {
private String requestA;
public RequestTypeA() {
route = "requestTypeA";
}
public String getRequestA() {
return requestA;
}
public void setRequestA(String requestA) {
this.requestA = requestA;
}
}
and RequestTypeB.java
public class RequestTypeB extends RouterRequest {
private String requestB;
public RequestTypeB() {
route = "requestTypeB";
}
public String getRequestB() {
return requestB;
}
public void setRequestB(String requestB) {
this.requestB = requestB;
}
}
And a result class, RouterResult.java:
public class RouterResult {
private String result;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
#Override
public String toString() {
return "RouterResult{" +
"result='" + result + '\'' +
'}';
}
}
Then, to invoke this Lambda, you will need a role that has the lambda:InvokeFunction permission. The code to invoke looks like:
public class RouterRunner {
private static final String AWS_ACCESS_KEY_ID = "<access key>";
private static final String AWS_SECRET_ACCESS_KEY = "<access secret>";
public static void main( String[] argv ) throws IOException {
AWSCredentials credentials = new BasicAWSCredentials( AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY );
AWSLambda lambda = AWSLambdaClientBuilder.standard()
.withRegion(Regions.US_WEST_2)
.withCredentials(new AWSStaticCredentialsProvider(credentials)).build();
RequestTypeA requestTypeA = new RequestTypeA();
requestTypeA.setRequestA("set from the runner, request type A");
ObjectMapper objectMapper = new ObjectMapper();
InvokeRequest invokeRequest = new InvokeRequest()
.withFunctionName("lambda-router")
.withPayload(objectMapper.writeValueAsString(requestTypeA));
invokeRequest.setInvocationType(InvocationType.RequestResponse);
InvokeResult invokeResult = lambda.invoke(invokeRequest);
String resultJSON = new String(invokeResult.getPayload().array(), StandardCharsets.UTF_8);
System.out.println( "result from lambda is " + resultJSON );
RouterResult routerResult = objectMapper.readValue(resultJSON, RouterResult.class);
System.out.println( "result.toString is " + routerResult.toString() );
RequestTypeB requestTypeB = new RequestTypeB();
requestTypeB.setRequestB("set from the runner, request type B");
invokeRequest = new InvokeRequest()
.withFunctionName("lambda-router")
.withPayload(objectMapper.writeValueAsString(requestTypeB));
invokeRequest.setInvocationType(InvocationType.RequestResponse);
invokeResult = lambda.invoke(invokeRequest);
resultJSON = new String(invokeResult.getPayload().array(), StandardCharsets.UTF_8);
System.out.println( "result from lambda is " + resultJSON );
routerResult = objectMapper.readValue(resultJSON, RouterResult.class);
System.out.println( "result.toString is " + routerResult.toString() );
}
}
There likely needs to be some error handling improvement and I'm sure you could make this a bit more efficient. But that's the overall idea. Ultimately on the Lambda side I convert the InputStream to a String and convert that String to some sort of object based on a common field in the request types. On the client side I convert the objects into JSON, send them out, and convert the result back from a JSON String back into the result object.

How to update/refresh list items of list view in oracle maf?

I have list of tasks. When I delete my one of the task my list still shows that task in the list but on server side i have updated list I am not able to refresh my list. I am getting new task array from server but not able to show it. When I launched my app again then it is showing the updated list. How can I get updated list without killing the app? Both the times I have updated array but not able to show it on the view.
public class ModelClass {
private String message;
private String statusCode;
private Response[] res = null;
protected transient PropertyChangeSupport _propertyChangeSupport = new PropertyChangeSupport(this);
public ModelClass() {
super();
clickEvent(new ActionEvent());
}
public static String taskId;
public void setTaskId(String taskId) {
System.out.print(taskId);
this.taskId = taskId;
}
public String getTaskId() {
return taskId;
}
public PropertyChangeSupport getPropertyChangeSupport() {
return _propertyChangeSupport;
}
public void setMessage(String message) {
String oldMessage = this.message;
this.message = message;
_propertyChangeSupport.firePropertyChange("message", oldMessage, message);
}
public String getMessage() {
return message;
}
public void setStatusCode(String statusCode) {
String oldStatusCode = this.statusCode;
this.statusCode = statusCode;
_propertyChangeSupport.firePropertyChange("statusCode", oldStatusCode, statusCode);
}
public String getStatusCode() {
return statusCode;
}
public void setRes(Response[] res) {
Response[] oldRes = this.res;
this.res = res;
System.out.println(res);
_propertyChangeSupport.firePropertyChange("res", oldRes, res);
System.out.println("refreshing here ");
}
public Response[] getRes() {
return res;
}
#Override
public String toString() {
return "ClassPojo [response = " + res + ", message = " + message + ", statusCode = " + statusCode + "]";
}
public void addPropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.removePropertyChangeListener(l);
}
public class Response {
private String taskId;
private String taskType;
private Integer taskTime;
private String taskName;
private PropertyChangeSupport _propertyChangeSupport = new PropertyChangeSupport(this);
Response(String taskId, String taskType, String taskName) {
super();
this.taskId = taskId;
this.taskType = taskType;
this.taskName = taskName;
}
public void setTaskId(String taskId) {
String oldTaskId = this.taskId;
this.taskId = taskId;
_propertyChangeSupport.firePropertyChange("taskId", oldTaskId, taskId);
}
public String getTaskId() {
return taskId;
}
public void setTaskType(String taskType) {
String oldTaskType = this.taskType;
this.taskType = taskType;
_propertyChangeSupport.firePropertyChange("taskType", oldTaskType, taskType);
}
public String getTaskType() {
return taskType;
}
public void setTaskTime(Integer taskTime) {
Integer oldTaskTime = this.taskTime;
this.taskTime = taskTime;
_propertyChangeSupport.firePropertyChange("taskTime", oldTaskTime, taskTime);
}
public Integer getTaskTime() {
return taskTime;
}
public void setTaskName(String taskName) {
String oldTaskName = this.taskName;
this.taskName = taskName;
_propertyChangeSupport.firePropertyChange("taskName", oldTaskName, taskName);
}
public String getTaskName() {
return taskName;
}
#Override
public String toString() {
return "ClassPojo [taskId = " + taskId + ", taskType = " + taskType + ", taskTime = " + taskTime +
", taskName = " + taskName + "]";
}
public void addPropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.removePropertyChangeListener(l);
}
}
protected transient ProviderChangeSupport providerChangeSupport = new ProviderChangeSupport(this);
public void addProviderChangeListener(ProviderChangeListener l) {
providerChangeSupport.addProviderChangeListener(l);
}
public void removeProviderChangeListener(ProviderChangeListener l) {
providerChangeSupport.removeProviderChangeListener(l);
}
public void clickEvent(ActionEvent actionEvent) {
try {
JSONObject paramsMap = new JSONObject();
paramsMap.put("userId", "1");
HttpURLConnection httpURLConnection = null;
try {
URL url = new URL("http://ec2-54-226-57-153.compute-1.amazonaws.com:8080/#########");
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setReadTimeout(120000);
httpURLConnection.setConnectTimeout(120000);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.connect();
OutputStream os = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
os.write(paramsMap.toString().getBytes());
bufferedWriter.flush();
bufferedWriter.close();
os.close();
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream is = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuilder builder = new StringBuilder();
String line = bufferedReader.readLine();
while (line != null) {
builder.append(line + "\n");
line = bufferedReader.readLine();
}
is.close();
if (httpURLConnection != null)
httpURLConnection.disconnect();
System.out.println(builder.toString());
JSONObject json = new JSONObject(builder.toString());
String status = json.optString("statusCode");
String message = json.optString("message");
String response = json.optString("response");
System.out.println(status);
System.out.println(message);
// System.out.println(response);
JSONArray objarr = json.optJSONArray("response");
Response[] temp_res = new Response[objarr.length()];
for (int i = 0; i < objarr.length(); i++) {
System.out.println(objarr.getJSONObject(i));
JSONObject obj = objarr.getJSONObject(i);
String task = obj.optString("taskName");
taskId = obj.optString("taskId");
String taskType = obj.optString("taskType");
System.out.println(task);
System.out.println(taskId);
System.out.println(taskType);
temp_res[i] = new Response(taskId, taskType, task);
}
setRes(temp_res);
} else {
if (httpURLConnection != null)
httpURLConnection.disconnect();
System.out.println("Invalid response from the server");
}
} catch (Exception e) {
e.printStackTrace();
if (httpURLConnection != null)
httpURLConnection.disconnect();
} finally {
if (httpURLConnection != null)
httpURLConnection.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I think you need to add providerChangeSupport.fireProviderRefresh("res");
and you have to make public method for providerChangeSupport.
Here is the link : https://community.oracle.com/message/13203364#13203364
Other than the fix suggested by Rashi Verma, there is one more change required.
The code snippet:
res = (Response[]) res_new.toArray(new Response[res_new.size()]);
setRes(res);
needs to be changed to:
Response[] temp_res;
temp_res = (Response[]) res_new.toArray(new
Response[res_new.size()]);
setRes(temp_res);
Currently, because the value of res is changed before invoking setRes, the propertyChangeEvent is not fired inside setRes. Both this propertyChangeEvent and the providerRefresh are needed for the changes you are making to start reflecting on the UI.

Spring BeanUtils.copyProperties not working

I want to copy properties from one object to another, both are of the same class. However it's not copying the fields. Here is the demo code:
public static void main(String[] args) throws Exception {
A from = new A();
A to = new A();
from.i = 123;
from.l = 321L;
System.out.println(from.toString());
System.out.println(to.toString());
BeanUtils.copyProperties(from, to);
System.out.println(from.toString());
System.out.println(to.toString());
}
public static class A {
public String s;
public Integer i;
public Long l;
#Override
public String toString() {
return "A{" +
"s=" + s +
", i=" + i +
", l=" + l +
'}';
}
}
And the output is:
A{s=null, i=123, l=321}
A{s=null, i=null, l=null}
A{s=null, i=123, l=321}
A{s=null, i=null, l=null}
Looks like I have to have setter/getters for the class:
public static void main(String[] args) throws Exception {
A from = new A();
A to = new A();
from.i = 123;
from.l = 321L;
System.out.println(from.toString());
System.out.println(to.toString());
BeanUtils.copyProperties(from, to);
System.out.println(from.toString());
System.out.println(to.toString());
}
public static class A {
public String s;
public Integer i;
public Long l;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public Integer getI() {
return i;
}
public void setI(Integer i) {
this.i = i;
}
public Long getL() {
return l;
}
public void setL(Long l) {
this.l = l;
}
#Override
public String toString() {
return "A{" +
"s=" + s +
", i=" + i +
", l=" + l +
'}';
}
}
Now the output is:
A{s=null, i=123, l=321}
A{s=null, i=null, l=null}
A{s=null, i=123, l=321}
A{s=null, i=123, l=321}

Resources