CommandTable Cystal Report Error - java

I have a Crystal Report that was written using a complex SQL and I'm trying to invoke that using the Crystal Report Java API. This report has a Command object associated with it.
I load the report and set the connection parameters.
Then I try to set the Connection information to the current JDBC Profile. Meaning Test Environment credentials.
I get an exception. I tried with Version 11. Version 12 both. None of them seems to be working.
I'm getting the exception when I invoke the following piece of code. This piece of code works just fine with reports without "Command" sqls.
try{
clientDoc.getDatabaseController().setTableLocation(
origTable, newTable);
}catch(Exception ex){
ex.printStackTrace();
}
See below for the entire code. Please reply if anyone knows how to work around this.
private static void changeDataSource(ReportClientDocument clientDoc,
String reportName, String tableName, String username,
String password, String connectionURL, String driverName,
String jndiName) throws ReportSDKException {
PropertyBag propertyBag = null;
IConnectionInfo connectionInfo = null;
ITable origTable = null;
ITable newTable = null;
// Declare variables to hold ConnectionInfo values.
// Below is the list of values required to switch to use a JDBC/JNDI
// connection
String TRUSTED_CONNECTION = "false";
String SERVER_TYPE = "JDBC (JNDI)";
String USE_JDBC = "true";
String DATABASE_DLL = "crdb_jdbc.dll";
String JNDI_OPTIONAL_NAME = jndiName;
String CONNECTION_URL = connectionURL;
String DATABASE_CLASS_NAME = driverName;
// Declare variables to hold database User Name and Password values
String DB_USER_NAME = username;
String DB_PASSWORD = password;
System.out.println("Trusted_Connection:" + TRUSTED_CONNECTION);
System.out.println("Server Type:" + SERVER_TYPE);
System.out.println("Use JDBC:" + USE_JDBC);
System.out.println("Database DLL:" + DATABASE_DLL);
System.out.println("JNDIOptionalName:" + JNDI_OPTIONAL_NAME);
System.out.println("Connection URL:" + CONNECTION_URL);
System.out.println("Database Class Name:" + DATABASE_CLASS_NAME);
System.out.println("DB_USER_NAME:" + DB_USER_NAME);
System.out.println("DB_PASSWORD:" + DB_PASSWORD);
// Obtain collection of tables from this database controller
if (reportName == null || reportName.equals("")) {
Tables tables = clientDoc.getDatabaseController().getDatabase()
.getTables();
for (int i = 0; i < tables.size(); i++) {
origTable = tables.getTable(i);
if (tableName == null || origTable.getName().equals(tableName)) {
newTable = (ITable) origTable;
newTable.setQualifiedName(origTable.getAlias());
connectionInfo = newTable.getConnectionInfo();
// Set new table connection property attributes
propertyBag = new PropertyBag();
// Overwrite any existing properties with updated values
propertyBag.put("Trusted_Connection", TRUSTED_CONNECTION);
propertyBag.put("Server Type", SERVER_TYPE);
propertyBag.put("Use JDBC", USE_JDBC);
propertyBag.put("Database DLL", DATABASE_DLL);
propertyBag.put("JNDIOptionalName", JNDI_OPTIONAL_NAME);
propertyBag.put("Connection URL", CONNECTION_URL);
propertyBag.put("Database Class Name", DATABASE_CLASS_NAME);
connectionInfo.setAttributes(propertyBag);
connectionInfo.setUserName(DB_USER_NAME);
connectionInfo.setPassword(DB_PASSWORD);
// Update the table information
try{
clientDoc.getDatabaseController().setTableLocation(
origTable, newTable);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
// Next loop through all the subreports and pass in the same
// information. You may consider
// creating a separate method which accepts
if (reportName == null || !(reportName.equals(""))) {
IStrings subNames = clientDoc.getSubreportController()
.getSubreportNames();
for (int subNum = 0; subNum < subNames.size(); subNum++) {
Tables tables = clientDoc.getSubreportController()
.getSubreport(subNames.getString(subNum))
.getDatabaseController().getDatabase().getTables();
for (int i = 0; i < tables.size(); i++) {
origTable = tables.getTable(i);
if (tableName == null
|| origTable.getName().equals(tableName)) {
newTable = (ITable) origTable;
newTable.setQualifiedName(origTable.getAlias());
// Change connection information properties
connectionInfo = newTable.getConnectionInfo();
// Set new table connection property attributes
propertyBag = new PropertyBag();
// Overwrite any existing properties with updated values
propertyBag.put("Trusted_Connection",
TRUSTED_CONNECTION);
propertyBag.put("Server Type", SERVER_TYPE);
propertyBag.put("Use JDBC", USE_JDBC);
propertyBag.put("Database DLL", DATABASE_DLL);
propertyBag.put("JNDIOptionalName", JNDI_OPTIONAL_NAME);
propertyBag.put("Connection URL", CONNECTION_URL);
propertyBag.put("Database Class Name",
DATABASE_CLASS_NAME);
connectionInfo.setAttributes(propertyBag);
connectionInfo.setUserName(DB_USER_NAME);
connectionInfo.setPassword(DB_PASSWORD);
// Update the table information
clientDoc.getSubreportController()
.getSubreport(subNames.getString(subNum))
.getDatabaseController()
.setTableLocation(origTable, newTable);
}
}
}
}
}

Add after this line of yours
connectionInfo.setPassword(DB_PASSWORD);
newTable.setConnectionInfo(connectionInfo);
//This will add connection parameters to the new table
Instead of
clientDoc.getDatabaseController().setTableLocation(origTable, newTable);
replace this with
clientDoc.getDatabaseController ().setTableLocation (newTable, tables.getTable(i));

Related

NotesException: A required argument has not been provided

My XPage gathers information which I use to populate a document in a different Domino database. I use a link button (so I can open another XPage after submission). The onClick code is as follows:
var rtn = true
var util = new utilities()
var hostURL = configBean.getValue("HostURL");
var userAttachment;
//set up info needed for checking duplicates
var attachName=getComponent("attachmentIdentifier").getValue();
var serialNbr = getComponent("serialNumber").getValue();
userAttachment = user+"~"+attachName;
var userSerial = user+"~"+serialNbr;
//Done setting info needed
//check for duplicates
rtn = utilBean.checkAttachmentName(userAttachment, userSerial)
//done
if(rtn==true){
var doc:Document = document1;
dBar.info("ALL IS GOOD");
var noteID:String=document1.getNoteID();
dBar.info("Calling saveNewAttachment using NoteID " + noteID )
rtn=utilBean.saveNewAttachment(session,noteID ); //<<< I get error here
dBar.info("rtn = " + rtn)
return "xsp-success";
view.postScript("window.open('"+sessionScope.nextURL+"')")
}else if (rtn==false){
errMsgArray = utilBean.getErrorMessages();
for(err in errMsgArray){
//for (i=0; i < errMsgArray.size(); i++){
dBar.info("err: "+ err.toString());
if (err== "nameUsed"){
//send message to XPXage
facesContext.addMessage(attachmentIdentifier.getClientId(facesContext) , msg(langBean.getValue("duplicateName")));
}
if(err=="serialUsed"){
//send message to XPXage
facesContext.addMessage(serialNumber.getClientId(facesContext) , msg(langBean.getValue("duplicateSerial")));
}
}
return "xsp-failure";
}
And the java code that delivers the error is this
public boolean saveNewAttachment(Session ses, String noteID)
throws NotesException {
debugMsg("Entering saveNewAttachment and NOTEID = "+noteID);
// this is used when the user saves an attachment to to the
// user profiles db
boolean rtn = false;
Document doc;
ConfigBean configBean = (ConfigBean)
ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(),
"configBean");
String dbName = (String) configBean.getValue("WebsiteDbPath");
debugMsg("A");
Database thisDB = ses.getDatabase(ses.getServerName(), dbName, false);
String value;
try {
debugMsg("noteID: "+noteID);
The next line throws the NotesException error
doc = thisDB.getDocumentByID("noteID");
debugMsg("C");
} catch (Exception e) {
debugMsg("utilitiesBean.saveAttachment: " + e.toString());
e.printStackTrace();
System.out.println("utilitiesBean.saveAttachment: " + e.toString());
throw new RuntimeException("utilitiesBean.saveAttachment: "
+ e.toString());
}
return rtn;
}
I might be going about this wrong. I want to save the document which the data is bound to the User Profile database but if I submit it I need to redirect it to a different page. That is why I am using a link, however, I am having a hard time trying to get the document saved.
Has document1 been saved before this code is called? If not, it's not in the backend database to retrieve via getDocumentByID().
I'm assuming this line has been copied into here incorrectly, because "noteID" is not a NoteID or a variable holding a NoteID, it's a string.
doc = thisDB.getDocumentByID("noteID");

How to implement a Sign in function by using Gigya API in JAVA?

I am trying to delete the accounts from Gigya DB, so we can reuse them to test our login function through Gigya. It seems the UID required for deletion come from login, so how am I suppose to do it in Java?
As mentioned by Ilan, firstly you'll need to include the Gigya Java SDK.
You can then look up the UID using either the Identity Access or Identity Query Tool within Gigya console and use the follow code to delete the account:
// delete user record
GSRequest deleteAccountRequest = new GSRequest(apiKey, secretKey, "accounts.deleteAccount");
//deleteAccountRequest.setAPIDomain("eu1.gigya.com"); // enable this if you're using the EU data centre
deleteAccountRequest.setUseHTTPS(true);
deleteAccountRequest.setParam("UID", uid);
GSResponse deleteAccountResponse = deleteAccountRequest.send();
if(deleteAccountResponse.getErrorCode()==0)
{
}
else
{
System.out.println("deleteAccountResponse failure: " + deleteAccountResponse.getLog());
}
Alternatively, if you want to delete users in batch, you can run a search using accounts.search and delete all the users within the results set:
int limit = 100;
String query = "select UID from accounts where ... " + limit; // add your query here i.e. email = 'someone#example.com'
String cursorId = "";
int objectsCount = limit;
GSRequest searchRequest;
ArrayList<String> uidList = new ArrayList<String>();
// send request
do
{
// check if we have an open cursor
if(cursorId.length() > 0)
{
// run next request in cursor
// set up request
searchRequest = new GSRequest(apiKey, secretKey, "accounts.search");
//searchRequest.setAPIDomain("eu1.gigya.com");
//searchRequest.setUseHTTPS(true);
// set timeout
searchRequest.setParam("timeout", 60000);
// set cursor id
searchRequest.setParam("cursorId", cursorId);
} else {
// run new request and open cursor
// set up request
searchRequest = new GSRequest(apiKey, secretKey, "accounts.search");
//searchRequest.setAPIDomain("eu1.gigya.com");
//searchRequest.setUseHTTPS(true);
// set timeout
searchRequest.setParam("timeout", 60000);
// set query
searchRequest.setParam("query", query);
// open cursor
searchRequest.setParam("openCursor", true);
}
GSResponse searchResponse = searchRequest.send();
if(searchResponse.getErrorCode()==0)
{
GSArray uids = new GSArray();
uids = searchResponse.getArray("results", uids);
for(int i=0; i<uids.length(); i++)
{
String uid;
try {
// retrieve uid and add to list of uids
uid = uids.getObject(i).getString("UID");
uidList.add(uid);
} catch (GSKeyNotFoundException e) {
}
}
cursorId = searchResponse.getString("nextCursorId", "");
objectsCount = searchResponse.getInt("objectsCount", 0);
}
else
{
System.out.println("searchRequest failure: " + searchResponse.getLog());
}
}
while (objectsCount >= limit);
for(int i=0; i<uidList.size(); i++)
{
String uid;
try {
uid = uidList.get(i);
// delete user record
GSRequest deleteAccountRequest = new GSRequest(apiKey, secretKey, "accounts.deleteAccount");
//deleteAccountRequest.setAPIDomain("eu1.gigya.com");
deleteAccountRequest.setUseHTTPS(true);
deleteAccountRequest.setParam("UID", uid);
GSResponse deleteAccountResponse = deleteAccountRequest.send();
if(deleteAccountResponse.getErrorCode()==0)
{
}
else
{
System.out.println("deleteAccountResponse failure: " + deleteAccountResponse.getLog());
}
} catch (Exception e) {
}
}

Java Storing Multiple Rows From Select Queries

This is actually a re-do of an older question of mine that I have completely redone because my old question seemed to confuse people.
I have written a Java program that Queries a database and is intended to retrieve several rows of data. I have previously written the program in Informix-4GL and I am using a sql cursor to loop through the database and store each row into a "dynamic row of record". I understand there are no row of records in Java so I have ended up with the following code.
public class Main {
// DB CONNECT VARIABLE ===========================
static Connection gv_conn = null;
// PREPARED STATEMENT VARIABLES ==================
static PreparedStatement users_sel = null;
static ResultSet users_curs = null;
static PreparedStatement uinfo_sel = null;
static ResultSet uinfo_curs = null;
// MAIN PROGRAM START ============================
public static void main(String[] args) {
try {
// CONNECT TO DATABASE CODE
} catch(Exception log) {
// YOU FAILED CODE
}
f_prepare(); // PREPARE THE STATEMENTS
ArrayList<Integer> list_id = new ArrayList<Integer>();
ArrayList<String> list_name = new ArrayList<String>();
ArrayList<Integer> list_info = new ArrayList<String>();
ArrayList<String> list_extra = new ArrayList<String>();
try {
users_sel.setInt(1, 1);
users_curs = users_sel.executeQuery();
// RETRIEVE ROWS FROM USERS
while (users_curs.next()) {
int lv_u_id = users_curs.getInt("u_id");
String lv_u_name = users_curs.getString("u_name");
uinfo_sel.setInt(1, lv_u_id);
uinfo_curs = uinfo_sel.executeQuery();
// RETRIEVE DATA FROM UINFO RELATIVE TO USER
String lv_ui_info = uinfo_curs.getString("ui_info");
String lv_ui_extra = uinfo_curs.getString("ui_extra");
// STORE DATA I WANT IN THESE ARRAYS
list_id.add(lv_u_id);
list_name.add(lv_u_name);
list_info.add(lv_ui_info);
list_extra.add(lv_ui_extra);
}
} catch(SQLException log) {
// EVERYTHING BROKE
}
// MAKING SURE IT WORKED
System.out.println(
list_id.get(0) +
list_name.get(0) +
list_info.get(0) +
list_extra.get(0)
);
// TESTING WITH ARBITRARY ROWS
System.out.println(
list_id.get(2) +
list_name.get(5) +
list_info.get(9) +
list_extra.get(14)
);
}
// PREPARE STATEMENTS SEPARATELY =================
public static void f_prepare() {
String lv_sql = null;
try {
lv_sql = "select * from users where u_id >= ?"
users_sel = gv_conn.prepareStatement(lv_sql);
lv_sql = "select * from uinfo where ui_u_id = ?"
uinfo_sel = gv_conn.prepareStatement(lv_sql)
} catch(SQLException log) {
// IT WON'T FAIL COZ I BELIEEEVE
}
}
}
class DBConn {
// connect to SQLite3 code
}
All in all this code works, I can hit the database once, get all the data I need, store it in variables and work with them as I please however this does not feel right and I think it's far from the most suited way to do this in Java considering I can do it with only 15 lines of code in Informix-4GL.
Can anyone give me advice on a better way to achieve a similar result?
In order to use Java effectively you need to use custom objects. What you have here is a lot of static methods inside a class. It seems that you are coming from a procedural background and if you try to use Java as a procedural language, you will not much value from using it. So first off create a type, you can plop it right inside your class or create it as a separate file:
class User
{
final int id;
final String name;
final String info;
final String extra;
User(int id, String name, String info, String extra)
{
this.id = id;
this.name = name;
this.info = info;
this.name = name;
}
void print()
{
System.out.println(id + name + info + extra);
}
}
Then the loop becomes:
List<User> list = new ArrayList<User>();
try {
users_sel.setInt(1, 1);
users_curs = users_sel.executeQuery();
// RETRIEVE ROWS FROM USERS
while (users_curs.next()) {
int lv_u_id = users_curs.getInt("u_id");
String lv_u_name = users_curs.getString("u_name");
uinfo_sel.setInt(1, lv_u_id);
uinfo_curs = uinfo_sel.executeQuery();
// RETRIEVE DATA FROM UINFO RELATIVE TO USER
String lv_ui_info = uinfo_curs.getString("ui_info");
String lv_ui_extra = uinfo_curs.getString("ui_extra");
User user = new User(lv_u_id, lv_u_name, lv_ui_info, lv_ui_extra);
// STORE DATA
list.add(user);
}
} catch(SQLException log) {
// EVERYTHING BROKE
}
// MAKING SURE IT WORKED
list.get(0).print();
This doesn't necessarily address the number of lines. Most people who use Java don't interact with databases with this low-level API but in general, if you are looking to get down to the fewest number of lines (a questionable goal) Java isn't going to be your best choice.
Your code is actually quite close to box stock JDBC.
The distinction is that in Java, rather than having a discrete collection of arrays per field, we'd have a simple Java Bean, and a collection of that.
Some examples:
public class ListItem {
Integer id;
String name;
Integer info;
String extra;
… constructors and setters/getters ellided …
}
List<ListItems> items = new ArrayList<>();
…
while(curs.next()) {
ListItem item = new ListItem();
item.setId(curs.getInt(1));
item.setName(curs.getString(2));
item.setInfo(curs.getInfo(3));
item.setExtra(curs.getString(4));
items.add(item);
}
This is more idiomatic, and of course does not touch on the several frameworks and libraries available to make DB access a bit easier.

Load database Field Values to A JCombobox

How to load values from an Oracle db to a JComboBox to make it easier for the user To Choose from I Have tried this:
Connection dbcon = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
dbcon = DriverManager.getConnection("
jdbc:oracle:thin:#localhost:1521:XE", "USERNAME", "PASSWORD");
Statement st = dbcon.createStatement();
String combo = "Select EMP_IDNUM from employees";
ResultSet res = st.executeQuery(combo);
while(res.next()){
String ids = res.getString("EMP_IDNUM");
String [] str = new String[]{ids};
cboId = new JComboBox(str);
}
} catch (Exception d) {
System.out.println(d);
}
This is Only getting me the first Value Into the JComboBox cboID. What Is the Best way to Load the entire Field Data (EMP_IDNUM) into the Jcombobox??
String [] str = new String[]{ids};
It means your String array is having only one ids value which you have loaded String ids = res.getString("EMP_IDNUM");
if(rs.getRow()>0){
String [] str = new String[res.getRow()];
int i=0;
while(res.next()){
str[i++] = res.getString("EMP_IDNUM");
}
}
JComboBox jcb = new JComboBox(str);
Instead of array you can use Vector also to create JComboBox.
you can use this code:
Vector v = new Vector();
while(res.next()){
String ids = res.getString("EMP_IDNUM");
v.add(ids)
}
JComboBox jcb = new JComboBox(v);
In this code you create a Vector with your Strings, and then invoke directly the JComboBox(Vector items) constructor of JComboBox
there are three important areas
a) close all JDBC Objects in the finally block, because these Object aren't, never GC'ed
try {
} catch (Exception d) {
System.out.println(d);
} finally {
try {
st.close()
res.close()
dbcon.close()
} catch (Exception d) {
//not important
}
}
b) don't to create any Objects inside try - catch - finally, prepare that before
meaning cboId = new JComboBox(str);
c) put all data from JDBC to the ComboBoxModel, prepare that before

replaceAll() method using parameter from text file

i have a collection of raw text in a table in database, i need to replace some words in this collection using a set of words.
i put all the term to be replace and its substitutes in a text file as below
min=admin
lelet=lambat
lemot=lambat
nii=nih
ntu=itu
and so on.
i have successfully initiate a variabel of File and Scanner to read the collection of the term and its substitutes.
i loop all the dataset and save the raw text in a string
in the same loop
i loop all the term collection and save its row to a string name 'pattern', and split the pattern into two string named 'term' and 'replacer'
in this loop i initiate a new string which its value is the string from the dataset modified by replaceAll(term,replacer)
end loop for term collection
then i insert the new string to another table in database
end loop for dataset
i do it manualy as below
replaceAll("min","admin")
and its works but its really something to code it manually for almost 2000 terms to be replace it.
anyone ever face this kind of really something..
i really need a help now desperate :(
package sentimenrepo;
import javax.swing.*;
import java.sql.*;
import java.io.*;
//import java.util.HashMap;
import java.util.Scanner;
//import java.util.Map;
/**
*
* #author herman
*/
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
File synonimV2 = new File("synV2/catatan_kata_sinonim.txt");
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet");
ResultSet RS = select.getResultSet();
Scanner scSynV2 = new Scanner(synonimV2);
while(RS.next()){
row++;
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
clean2 cleanv2 = new clean2();
newTweet = cleanv2.cleanTweet(tweet);
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+newTweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
return row;
}
class clean2{
public clean2(){}
public String cleanTweet(String tweet){
File synonimV2 = new File("synV2/catatan_kata_sinonim.txt");
String pattern = "";
String term = "";
String replacer = "";
String newTweet="";
try{
Scanner scSynV2 = new Scanner(synonimV2);
while(scSynV2.hasNext()){
pattern = scSynV2.next();
term = pattern.split("=")[0];
replacer = pattern.split("=")[1];
newTweet = tweet.replace(term, replacer);
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println(newTweet+"\n"+tweet);
return newTweet;
}
}
}
update
ive just realize that the code actually works but only for the first row in database, the second row and so on stand still. here is i update the newest code i ve build
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet limit 2,10");
ResultSet RS = select.getResultSet();
FileReader readSyn = new FileReader("synV2/catatan_kata_sinonim.txt");
BufferedReader buffSyn = new BufferedReader(readSyn);
while(RS.next()){
row++;
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
String pattern = "";
while((pattern=buffSyn.readLine())!=null){
String patternTerm = pattern.split("=")[0];
String patternSubs = pattern.split("=")[1];
tweet = tweet.replaceAll("\\s"+patternTerm, patternSubs);
}
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+tweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
// System.out.println(e.getMessage());
}
Thread.sleep(100);
return row;
}
}
Opening the synonym file and iterating over 2,000 lines for every row in your ResultSet is a bit wasteful.
Load your synonyms into an in-memory Map once, keyed by unique misspelt term, then do a lookup on the map for every row in your result set, and replace as necessary.
Let us use both solutions to build a single solution for you:
First, you create a HashMap with all your keys:
public static HashMap<String, String> getMap() {
//your version would read from the file
HashMap<String,String> myMap=new HashMap<String,String>();
myMap.put("min", "admin");
myMap.put("lelet", "lambat");
myMap.put("lemot", "lambat");
myMap.put("nii", "nih");
myMap.put("ntu", "itu");
return(myMap);
}
Second, you create a pattern that contains all the keys in your hashmap:
public static String getPattern(HashMap<String,String> mapReplacement) {
String pattern="";
for (String s : mapReplacement.keySet()) {
if (!pattern.isEmpty()) {
pattern=pattern+"|";
}
pattern=pattern+s;
}
return(pattern);
}
Next, you can create a cleanTweet method that uses both structures you created:
public static String cleanTweet(String tweet, Pattern pattern,HashMap<String, String> myMap) {
String newTweet=tweet;
Matcher matcher = pattern.matcher(newTweet);
int start=0;
while (matcher.find()) {
String key=matcher.group();
String replacement=myMap.get(key);
if (replacement!=null) {
newTweet=newTweet.replace(key, replacement );
}
}
return(newTweet);
}
This might require some tweaking to perfect (I onyl tested a few cases), but the point is that you are going to iterate a single time in your keys and then iterate only on your tweets.
I hope it helps.
I didn't try, but it seems to me that you've almost got it - just replace this line:
newTweet = tweet.replace(term, replacer);
with this:
tweet = tweet.replaceAll(term, replacer);
As you're not using newTweet any more, return tweet:
return tweet;
You should also delete the newTweet declaration.
Also, you shouldn't read Scanner to read lines. Use FileReader instead.
thanks folks
i ve found the answer why the code is not working,
the txt file containing terms and its substitutes should be initiated each time the program read a row from database.
the code would be like this
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet limit 2,10");
ResultSet RS = select.getResultSet();
while(RS.next()){
row++;
FileReader readSyn = new FileReader("synV2/catatan_kata_sinonim.txt");
BufferedReader buffSyn = new BufferedReader(readSyn);
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
String pattern = "";
while((pattern=buffSyn.readLine())!=null){
String patternTerm = pattern.split("=")[0];
String patternSubs = pattern.split("=")[1];
tweet = tweet.replaceAll("\\s"+patternTerm, patternSubs);
}
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+tweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
// System.out.println(e.getMessage());
}
Thread.sleep(100);
return row;
}
}
but im actually want to apply the code in which rlinden made above, but cant figure it out how to call the cleanTweet function.

Categories