Skip to content
This repository has been archived by the owner on Nov 8, 2021. It is now read-only.

Commit

Permalink
Compose a whole message from its parts when editing queue
Browse files Browse the repository at this point in the history
Thanks Tomáš Jiříček for the initial implementation.
Partly fixes issue #152.
  • Loading branch information
kparal committed May 5, 2013
1 parent 724fcd1 commit e1fce31
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/esmska/data/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class Config extends Object implements Serializable {
/** mutex whether config already loaded from disk */
private static boolean loaded = false;

private static final String LATEST_VERSION = "1.3";
private static final String LATEST_VERSION = "1.4";
private static final Logger logger = Logger.getLogger(Config.class.getName());

private String version = "";
Expand Down
4 changes: 2 additions & 2 deletions src/esmska/data/Envelope.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ public ArrayList<SMS> generate() {
msgText += signature;
}
}
String messageId = SMS.generateID();
// cut out the messages
for (int i=0;i<msgText.length();i+=limit) {
String cutText = msgText.substring(i,Math.min(i+limit,msgText.length()));
SMS sms = new SMS(c.getNumber(), cutText, c.getGateway());
sms.setName(c.getName());
SMS sms = new SMS(c.getNumber(), cutText, c.getGateway(), c.getName(), messageId);
list.add(sms);
}
}
Expand Down
70 changes: 69 additions & 1 deletion src/esmska/data/Queue.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Timer;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;

/** Class representing queue of SMS
Expand Down Expand Up @@ -95,7 +96,7 @@ private Queue() {
public static Queue getInstance() {
return instance;
}

/** Get all SMS in the queue.
* This is a shortcut for getAll(null). */
public List<SMS> getAll() {
Expand Down Expand Up @@ -166,6 +167,28 @@ public List<SMS> getAllWithStatus(SMS.Status status, String gatewayName) {
return Collections.unmodifiableList(list);
}

/** Get all SMS (fragments) in the queue with a specified ID.
* The queue is always sorted by the gateway name, the messages are not sorted.
* @param id message ID. Must not be empty.
* @return unmodifiable list of SMS with the specified ID.
*/
public List<SMS> getAllWithId(String id) {
Validate.notEmpty(id);
List<SMS> list = new ArrayList<SMS>();

synchronized(queue) {
for (Collection<SMS> col : queue.values()) {
for (SMS sms : col) {
if (StringUtils.equals(sms.getId(), id)) {
list.add(sms);
}
}
}
}

return Collections.unmodifiableList(list);
}

/** Add new SMS to the queue. May not be null.
* @return See {@link Collection#add}.
*/
Expand Down Expand Up @@ -244,6 +267,19 @@ public boolean remove(SMS sms) {
}
return removed;
}

/** Remove all SMS with a specified ID from the queue.
* @param id SMS to be removed. Not null.
*/
public void remove(String id) {
Validate.notEmpty(id);

synchronized(queue) {
for (SMS sms : getAllWithId(id)) {
remove(sms);
}
}
}

/** Remove all SMS from the queue. */
public void clear() {
Expand Down Expand Up @@ -489,6 +525,38 @@ public void setSMSFailed(SMS sms) {
timer.start();
markIfReady(sms);
}

/**
* Extract all message fragments (according to ID) from the queue and join them
* into a full message.
* @param id id of all the message fragments; not empty
* @param remove whether to remove all the fragments from the queue in the process
* @return sms the whole message with concatenated fragments' text; or null if
* no such ID was present
*/
public SMS extractSMS(String id, boolean remove) {
Validate.notEmpty(id);
SMS sms;

synchronized(queue) {
List<SMS> fragments = getAllWithId(id);
if (fragments.isEmpty()) {
return null;
}

SMS head = fragments.get(0);
sms = new SMS(head.getNumber(), "", head.getGateway(), head.getName(), null);
for (SMS fragment : fragments) {
sms.setText(sms.getText() + fragment.getText());
}

if (remove) {
remove(id);
}
}

return sms;
}

/** Check if sms is ready and set status if it is */
private void markIfReady(SMS sms) {
Expand Down
36 changes: 33 additions & 3 deletions src/esmska/data/SMS.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;

Expand All @@ -25,6 +26,7 @@ public class SMS {
private Status status = Status.NEW; //sms status
private String supplMsg = ""; //supplemental message from gateway about remaining credit, etc
private Tuple<Problem, String> problem; //problem enum, string param
private String id; //message ID, useful when splitting/joining message parts

/** Status of SMS */
public static enum Status {
Expand All @@ -40,22 +42,31 @@ public static enum Status {
SENT;
}

/** Shortcut for SMS(number, text, gateway, null). */
/** Shortcut for SMS(number, text, gateway, null, null). */
public SMS(String number, String text, String gateway) {
this(number, text, gateway, null);
this(number, text, gateway, null, null);
}

/** Constructs new SMS. For detailed parameters restrictions see individual setter methods.
* @param number not null nor empty
* @param text not null
* @param gateway not null nor empty
* @param name
* @param id
*/
public SMS(String number, String text, String gateway, String name) {
public SMS(String number, String text, String gateway, String name, String id) {
setNumber(number);
setText(text);
setGateway(gateway);
setName(name);
setId(id);
}

/** Generate a new random message ID and return it. */
public static String generateID() {
String newId = Long.toString(System.currentTimeMillis());
newId += "#" + RandomStringUtils.randomAlphanumeric(4);
return newId;
}

/** Get signature matching current gateway or null if no such found. */
Expand Down Expand Up @@ -133,6 +144,13 @@ public Status getStatus() {
public String getName() {
return name;
}

/** Get the message ID. Never empty. This ID is used to mark different
* parts (fragments) of the same message - they share its ID.
*/
public String getId() {
return id;
}

/** Supplemental message from gateway. Never null. */
public String getSupplMsg() {
Expand Down Expand Up @@ -216,6 +234,18 @@ public void setProblem(Tuple<Problem, String> problem) {
}
this.problem = problem;
}

/** Set the message ID. If empty or null, a random ID is generated. This ID
* is used to mark different parts (fragments) of the same message - they
* share its ID.
*/
public void setId(String id) {
if (StringUtils.isEmpty(id)) {
this.id = generateID();
} else {
this.id = id;
}
}
// </editor-fold>

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/esmska/gui/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ public void eventOccured(ValuedEvent<HistoryFrame.Events, Record> e) {
return;
}

SMS sms = new SMS(record.getNumber(), record.getText(), record.getGateway());
sms.setName(record.getName());
SMS sms = new SMS(record.getNumber(), record.getText(),
record.getGateway(), record.getName(), null);

Context.mainFrame.getContactPanel().clearSelection();
Context.mainFrame.getSMSPanel().setSMS(sms);
Expand Down
4 changes: 2 additions & 2 deletions src/esmska/gui/MainFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -941,8 +941,8 @@ public void eventOccured(ValuedEvent<QueuePanel.Events, SMS> e) {
}
}
//edit the message
smsPanel.setSMS(sms);
queue.remove(sms);
SMS smsToEdit = queue.extractSMS(sms.getId(), true);
smsPanel.setSMS(smsToEdit);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/esmska/gui/QueuePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ public void actionPerformed(ActionEvent e) {
if (deleteOption.equals(pane.getValue())) {
for (Object o : toRemove) {
SMS sms = (SMS) o;
queue.remove(sms);
queue.remove(sms.getId());
}
}

Expand Down
1 change: 1 addition & 0 deletions src/esmska/persistence/ExportManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public static void exportQueue(Collection<SMS> queue, OutputStream out) throws I
sms.getNumber(),
sms.getGateway(),
sms.getText(),
sms.getId()
});
}
writer.flush();
Expand Down
5 changes: 3 additions & 2 deletions src/esmska/persistence/ImportManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ public static ArrayList<SMS> importQueue(File file) throws Exception {
String number = reader.get(1);
String gateway = reader.get(2);
String text = reader.get(3);

SMS sms = new SMS(number, text, gateway, name);
String id = reader.get(4);

SMS sms = new SMS(number, text, gateway, name, id);
queue.add(sms);
} catch (Exception e) {
logger.severe("Invalid queue record: " + reader.getRawRecord());
Expand Down
2 changes: 1 addition & 1 deletion src/esmska/resources/l10n.properties
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ ExportManager.export_failed=Contact export failed!
ExportManager.export_ok=Contact export finished successfully
ExportManager.export_ok!=Contact export finished successfully!
ExportManager.contact_list=Contact list (contact name, telephone number, default gateway)
ExportManager.sms_queue=SMS queue to be sent (recipient name, recipient number, gateway, message text, sender name, sender number)
ExportManager.sms_queue=SMS queue to be sent (recipient name, recipient number, gateway, message text, message ID)
ExportManager.history=Sent messages history (date, recipient name, recipient number, gateway, message text, sender name, sender number)
ExportManager.login=Usernames and password to individual gateways (gateway name, user login, user password)
ExportManager.export_info=<html>You can export your contacts to the CSV or vCard file. These are<br>\ntext files with all the data clearly visible and readable.<br>\nBy using import function you can later on load this data back to Esmska<br>\nor use it other way.<br><br>\nThe file in vCard format is standardized and you can use it<br>\nin many other applications. The CSV file has very simple contents<br>\nand every program creates it a little differently. If you need to change it's<br>\nstructure to import it in other program you can use some spreadsheet,<br>\neg. freely available OpenOffice Calc (www.openoffice.org).<br><br>\nThe file will be saved in the UTF-8 encoding.</html>
Expand Down
23 changes: 23 additions & 0 deletions src/esmska/update/LegacyUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import java.io.File;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand All @@ -22,6 +24,7 @@
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
Expand All @@ -47,6 +50,26 @@ public static void update() throws Exception {
logger.log(Level.INFO, "Updating from legacy version {0} to current version {1}",
new Object[]{version, Config.getLatestVersion()});

//changes to 1.4
if (Config.compareProgramVersions(version, "1.4") < 0) {
//add message ID to queue
logger.fine("Updating queue to add message IDs...");
try {
Field queueFileField = PersistenceManager.class.getDeclaredField("queueFile");
queueFileField.setAccessible(true);
File queueFile = (File) queueFileField.get(null);

List<String> lines = FileUtils.readLines(queueFile, "UTF-8");
ArrayList<String> newLines = new ArrayList<String>();
for (String line : lines) {
newLines.add(line + ",");
}
FileUtils.writeLines(queueFile, "UTF-8", newLines);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Updating queue file failed", ex);
}
}

//changes to 0.8.0
if (Config.compareProgramVersions(version, "0.8.0") < 0) {
//set country prefix from locale
Expand Down

0 comments on commit e1fce31

Please sign in to comment.