how to reset recipient list from javax.mail.internet.MimeMessage - java

I have a scenario in which I need to send bulk emails to senders. I can send only 10 mails at a time.
So I set all my mail contents in variable and then add only ten recipients at a time.
Then after I send email, I again add ten next receipients to it.
private void addRecipients(Message pMessage, List pRecipients, Message.RecipientType pType, int pNum, int pOffset, int pBulkSize){
for (int i = 0; i < pRecipients.size(); i++) {
int offset = pNum + i;
if (pBulkSize != 0 && (offset < pOffset || offset >= pOffset + pBulkSize)) {
continue;
}
Address a;
Object r = pRecipients.get(i);
pMessage.addRecipient(pType, a);
}
But the problem is I am not able to remove the last ten receipients from the variable.
Transport.send(message);
After this line, my loop restarts and again the addRecipients method is called. But now the object
MimeMessage message = getIntialEmailConfiguration();
message has previous recipients as well.
I want to know how to reset that one property and remove existing recipients.

Use the Message.setRecipients which will remove and apply multiple addresses.
Your code example won't compile because 'Address a' is never assigned a value.

Related

JSON with multi tasking

I am new to Qt C++ development. I have a processor which will control the Hardware. From server (Java) I will send the instructions to that Hardware. According to that particular instruction, it is going to perform. This is the general idea of my project.
Basic control instructions were written on board. Now What I want and What is the problem I am going to describe that? Sorry for my poor English.
I am going to send the JSON string from the server. For example
working|pq|0|1
From web socket I will receive the string
else if(message.contains("working")) {
emit OnMsgRecievedConnect("connect");
workingpq = message;
qDebug() << workingpq;
}
Now I have received a string from the server. I have taken that string into another thread for giving instruction to Hardware.
workingvaluepq = EchoClient::workingpq ;
qDebug() << "End pq value Received from server :" << workingvaluepq ;
QStringList pq = workingvaluepq.split("|");
int pqSize = pq.size(); // get the pq list size;
qDebug() << "End pq size :" << pqSize;
if(pqSize == 5){
p = pq[3];
q = pq[4];
}
int pInt = p.toInt(&ok);
int qInt = q.toInt(&ok);
if(!ok && pqSize == 5){
pend = pInt;
}
if(!ok && pqSize == 5){
qend = qInt;
}
pend = pInt;
qend = qInt;
if(pqSize == 1 ){
pend = jread->endvaluep;
qend = jread->endvalueq;
}
while(true)
{ (All other stuff here)
if(pqSize == 5){
if (pend == pstart && qend == qstart)
{
Jsonendflag = 1;
}
}
if(pqSize == 1){
if (pend == pstart && qend == qstart)
{
Rightstopflag = 1;
}
}
So when this point (whatever we fixed) reached the particular task, finally it will get stop. Maybe above code have some experienced issue. So a person can help me to improve the code. One more question, This is only one task, I have tried.
Note: pstart, qstart, pend, qend these things defined in the onboard JSON file. Just I will read and execute so reading executing is not a big deal
If I receive the multiple string (task) from server machine have to complete the task one by one. For example, will receive the string like given below
working|xy|2|3*working1|xy|8|7*working3|xy|12|15*working4|xy|17|20
Above string have a four different task, I will receive in same time, now I want to split and complete the task one by one continuously. I hope here so many experienced people can help and solve this issue.
After you split using *, use a loop to process your tasks one by one.
const QStringList taskList = QString("working|xy|2|3*working1|xy|8|7*working3|xy|12|15*working4|xy|17|20").split('*');
for (const QString& task : taskList)
{
auto params = task.split('|');
/* Perform 1 task */
// ...
}
/* Report back to server */
// ...
The code above uses a C++ ranged-for-loop.
You can do the same using an older for-loop:
for (int i = 0; i < taskList.count(); ++i)
{
auto params = taskList[i].split('|');
/* Perform 1 task */
// ...
}

Verifying the data from two arraylist and delete it

I have a master arraylist call toBeDeleted which stored timestamp and email. The following are the sample data inside the toBeDeleted arraylist
[1507075234, bunny#outlook.com]
I have one arraylist call logData1 which stored status,email,timestamps and ID. The following are the sample data inside the logData1 arraylist.
[16, bunny#outlook, 1507075234, 0OX9VQB-01-00P-02]
I hope to delete the data inside the logData1 arraylist by verifying the timestamp first with timestamps stated in toBeDeleted1 arraylist, if the timestamp matched, I will check the email for both arraylist. If both of them are matched, I would like to delete away all the data (status,email,timestamp,ID). But I cant make it work
this is my sample output from my source code
[16, bunny#outlook.com, 1507075234, 0OX9VQB-01-00P-02]
The data inside toBeDeleted1 is :[1507075234, bunny#outlook.com]
The time1 is :1507075234
The email1 is :bunny#outlook.com
The time is :1507075234
The emails is :bunny#outlook.com
The data is :bunny#outlook.com
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -3
at java.util.ArrayList.elementData(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at EmailReporting.main(EmailReporting.java:83)
This is my sample program
System.out.println(logData1);
System.out.println("The data inside toBeDeleted1 is :"+toBeDeleted1);
for(int v = 0;v<toBeDeleted1.size();v++) //look through the logdata1 for removing the record base on timestamp
{
String time1 = toBeDeleted1.get(v);
String email1 = toBeDeleted1.get(v+1);
System.out.println("The time1 is :"+time1);
System.out.println("The email1 is :"+email1);
for(int f = logData1.size();f>logData1.size()-1;f--)
{
// System.out.println(logData1.size());
// System.out.println("The data in logdata1 is "+logData1.get(f-2));
if(time1.equals(logData1.get(f-2)))
{
System.out.println("The time is :"+logData1.get(f-2));
System.out.println("The emails is :"+logData1.get(f-3));
if(email1.equals(logData1.get(f-3)))
{
System.out.println("The data is :"+logData1.get(f-3));
logData1.remove(f-1);
logData1.remove(f-2);
logData1.remove(f-3);
logData1.remove(f-4);
f-=4;
}
}
}
}
The error occurred after this line of code executed
System.out.println("The data is :"+logData1.get(f-3));
You can find elements in the list in order using Collections.indexOfSubList:
List<String> toFind = Arrays.asList(time1, email1);
int emailIndex = Collections.indexOfSubList(logData1, toFind);
A similar lastIndexOfSubList method also exists. That might be more appropriate for your use case.
You can then use this to remove the elements from toFind:
int emailIndex = Collections.lastIndexOfSubList(logData1, toFind);
if (emailIndex >= 1) {
logData1.subList(emailIndex-1, emailIndex+3).clear();
}
Just do this in a loop to keep going until all occurrences have been removed.
Note that just doing this in a loop naively will keep on searching over the tail of the list repeatedly. Instead, you can use subList to "chop" the end of the list, to avoid re-searching it:
List<String> view = logData1;
int emailIndex;
while ((emailIndex = Collections.lastIndexOfSubList(view, toFind)) >= 1) {
logData1.subList(emailIndex-1, emailIndex+3).clear();
view = logData1.subList(0, emailIndex-1);
}
Additionally, note that deleting from the middle of an ArrayList is inefficient, because the elements after the ones you delete have to be shifted down. This is why using subList(...).clear() is better, because it does all of those shifts at once. But if you are removing lots of 4-element batches, you can do better.
Instead of the subList(...).clear(), you can set the bits of elements to be deleted into a BitSet:
List<String> view = logData1;
BitSet bits = new BitSet(logData1.size());
int emailIndex;
while ((emailIndex = Collections.lastIndexOfSubList(view, toFind)) >= 1) {
bits.set(emailIndex-1, emailIndex+3);
view = logData1.subList(0, emailIndex-1);
}
And then shift all the elements down at once, discarding the elements you want to delete:
int dst = 0;
for (int src = 0; src < logData1.size(); ++src) {
if (!bits.get(src)) {
logData1.set(dst++, logData1.get(src));
}
}
And now truncate the list:
logData1.subList(dst, logData1.size());

How to apply the tempo extracted from track 1 to other tracks of a MIDI file?

I am trying to extract the tempo of a melody from the first track of a midi file and apply it to the rest of the tracks containing the note events.
Bascically I've been trying to replace the Thread.sleep() method after the noteOn() message which is playing a note for a fixed time interval everytime. Hence I'm losing the tempo of the entire track.
I was successful in extracting the tempo information from the first track from a previously asked question How does Midi TEMPO message apply to other tracks? but am unable to apply it to the rest of the tracks.
Is there a particular function that does that? I tried searching but couldn't find one.
Here is my code for reference.
int trackNumber = 0;
for (Track track : sequence.getTracks()) {
trackNumber++;
System.out.println();
for (int i=0; i < track.size(); i++) {
MidiEvent event = track.get(i);
MidiMessage message = event.getMessage();
if (message instanceof MetaMessage) {
MetaMessage mm = (MetaMessage) message;
if(mm.getType()==SET_TEMPO){
byte[] data = mm.getData();
int tempo = (data[0] & 0xff) << 16 | (data[1] & 0xff) << 8 | (data[2] & 0xff);
int bpm = 60000000 / tempo;
}
}
if (message instanceof ShortMessage) {
ShortMessage sm = (ShortMessage) message;
if (sm.getCommand() == NOTE_ON) {
int key = sm.getData1();
int velocity = sm.getData2();
channels[0].noteOn(key,velocity);
Thread.sleep(280);//Pays all the note for fixed duration
}
else if (sm.getCommand() == NOTE_OFF) {
int key = sm.getData1();
int velocity = sm.getData2();
channels[0].noteOff(key);
}
}
}
System.out.println();
}
}
Events in multiple tracks happen concurrently, so you cannot handle the tracks separately.
You have to either
put all events into a single list, and sort them by their timestamp (but ensure that events with the same time stamp keep their order, so use a stable sorting algorithm); or
have a current position for each track, and when determining which event is the next, search through all the tracks for a yet-unused event with the smallest timestamp.
Please note that the tempo can change during playback, so a single bpm value does not suffice. See How to correctly convert MIDI ticks to milliseconds? and How can I parse a tempo of midi using Java?.

Foreach not hitting last item

I have a foreach that is suppose to go through and arraylist and perform an action every time an item changes.
So it for something like:
ID | Request
1 | z
2 | e
it sends an email to 1 saying "You have 1 request". Then an email to 2 "You have 1 request" and so on.
My loop doesn't address the last item when there's only 2 items in the list and I'm having a difficult time trying to figure out the elegant way to address it.
Integer managerId = null;
Integer previousManagerId = null;
if(requests != null && requests.size() > 0){
for(Request request : requests){
managerId = request.getId();
if((!managerId.equals(previousId) && previousId != null)){
e.sendEmail(previousId, numReq.toString());
numReq = 0;
}
numReq++;
previousId = managerId;
}
//Suppose to address the last item. Fails when size == 2
if((!managerId.equals(previousId) && previousId != null)){
eusendEmail(previousId, numReq.toString());
}
The last statement of the loop ensures that previousId is always equal to managerId after the loop ends, so it can never go into the if.
I think you always want to send the last email because you know there was at least one request.
You have to save the previousId outside the for each because it will delet this value every time it goes trough the next object ;)
But why are you doing the first if? Wouldn't the foreach do that anyway?
How if you try like this:
String managerId = "";
for(Request request : requests){
managerId = request.getId();
if(!managerId.equals(previousId)){
request.sendEmail(previousId, numReq.toString());
numReq = 0;
}
numReq++;
}

Iterating through two arrays, having trouble with indices

I have a question about creating dynamic arrays and iterating through these arrays. I have a method setVoltage that takes as parameters a string and a double value. I needed some way to store these values so I created two arrays. What i need to do is iterate through the String array to see if the string parameter already exists and if it does, to set the corresponding voltage at that index. If it doesn't exist, i need to add the string device to the string array and also add the double voltage to the double array. Can someone check out my code and see what I am missing? I'm running into trouble because I want the array to realize the string is already in the array, or append it to the end of the array but I'm stuck on how to use index variables to achieve this. Thank you!
public final int sizeArray = 10;
private String[] deviceList = new String[sizeArray];
public double[] voltList = new double[sizeArray];
public synchronized void setVoltage(String device, double voltage) {
int index = 0;
for(int i = 0; i < deviceList.length; i++ ){
//if the device name already exists in the device array, overwrite voltage at that index
if(this.deviceList[i].equals(device)){
index = i;
voltList[index] = voltage;
}else{
//set deviceList[i] equal to device, set voltList[i] equal to voltage
deviceList[i] = device;
voltList[i] = voltage;
index++;
}
}
}
It sounds like perhaps you want a Map<String,Double> instead. This will let you store voltage values keyed by device name, and you can easily find, insert, and remove devices. See, for example, HashMap:
Map<String,Double> deviceVoltages = new HashMap<String,Double>();
deviceVoltages.put("liquifier", 8.4);
deviceVoltages.put("reflarbulator", 900.0);
deviceVoltages.put("liquifier", 13.3); // replaces previous 8.4
System.out.println(deviceVoltages.get("liquifier"));
deviceVoltages.remove("reflarbulator");
Your example code then reduces to simply:
private Map<String,Double> deviceVoltages = new HashMap<String,Double>();
public synchronized void setVoltage(String device, double voltage) {
deviceVoltages.put(device, voltage);
}
Performance will exceed that of your array, and you will not have a hard-coded limit on number of devices.
See generic Map documentation for links to other types of maps in the JDK.
See also ConcurrentHashMap if a finer synchronization granularity is desired and/or acceptable.
An alternative, if you must use arrays, is to create a Device class that encapsulates all the relevant information about a device and use a single array to simplify your logic, e.g.:
static class Device {
String name;
double voltage;
}
Device[] devices = new Device[10];
You can add new devices by replacing a null element in the array. You can update devices by finding the one with the specified name and changing its voltage field. You can optionally use a List<Device> to avoid hard-coded size limits.
It would be way better to use a Map<String,Double> in this scenario. But if you still want to use two arrays, your current code is not appending to the end of the array. Say if i=0 and deviceList[i] != device , then your code immediately overwrites deviceList[i] with the new value in the else block rather than appending it to the end of the array. To append, you have to move the code in the else part to after the for loop.
Your code will always overwrite the device if the device name was not found. It would be better if you used a Map but if you are required to use arrays you can try the following
for(int i = 0; i < deviceList.length; i++ ){
//if the device name already exists in the device array, overwrite voltage at that index
if(this.deviceList[i].equals(device)){
voltList[i] = voltage;
break;
}else if (deviceList[i] == null) {
//set deviceList[i] equal to device, set voltList[i] equal to voltage
deviceList[i] = device;
voltList[i] = voltage;
break;
}
}
You'll have to write some additional code to deal with a full array.
This is how I would do it as-is:
public void setOrAppend(String device, double voltage) {
int index = 0;
for ( ; index < deviceList.length; i++) {
if (device.equals(deviceList[index]) || deviceList[index] == null) {
break;
}
}
if (index == deviceList.length) {
deviceList = Arrays.copyOf(deviceList, deviceList.length + 1);
voltList = Arrays.copyOf(voltList, voltList.length + 1);
}
deviceList[index] = device;
voltList[index] = voltage;
}
I would recommend doing the set logic outside the loop. Additionally I would also recommend a Map for this kind of scenario since this kind of logic is simpler. A Map will already do what you are asking automatically (replace if exists otherwise append).

Categories