Add more warnings source to 1.6) and fix warnings
[jvcard.git] / src / be / nikiroo / jvcard / remote / Server.java
index 79547c9ddc38cc10058da648f70e909158751ed4..6cba0c33cbb09047ed09f4004f88266e9ee4193d 100644 (file)
@@ -11,16 +11,16 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.ResourceBundle;
 
 import be.nikiroo.jvcard.Card;
 import be.nikiroo.jvcard.Contact;
 import be.nikiroo.jvcard.Data;
 import be.nikiroo.jvcard.parsers.Format;
 import be.nikiroo.jvcard.parsers.Vcard21Parser;
-import be.nikiroo.jvcard.remote.Command.Verb;
-import be.nikiroo.jvcard.resources.Bundles;
-import be.nikiroo.jvcard.resources.StringUtils;
+import be.nikiroo.jvcard.remote.SimpleSocket.BlockAppendable;
+import be.nikiroo.jvcard.resources.RemoteBundle;
+import be.nikiroo.jvcard.resources.RemotingOption;
+import be.nikiroo.utils.StringUtils;
 
 /**
  * This class implements a small server that can listen for requests to
@@ -34,7 +34,7 @@ import be.nikiroo.jvcard.resources.StringUtils;
  * </p>
  * 
  * @author niki
- *
+ * 
  */
 public class Server implements Runnable {
        private ServerSocket ss;
@@ -59,9 +59,9 @@ public class Server implements Runnable {
         */
        public Server(int port) throws IOException {
                this.port = port;
-               ResourceBundle bundle = Bundles.getBundle("remote");
+               RemoteBundle bundle = new RemoteBundle();
                try {
-                       String dir = bundle.getString("SERVER_DATA_PATH");
+                       String dir = bundle.getString(RemotingOption.SERVER_DATA_PATH);
                        dataDir = new File(dir);
                        dataDir.mkdir();
 
@@ -88,7 +88,7 @@ public class Server implements Runnable {
                        SimpleSocket c = new SimpleSocket(new Socket((String) null, port),
                                        "special STOP client");
                        c.open(true);
-                       c.sendCommand(Verb.STOP);
+                       c.sendCommand(Command.STOP);
                        c.close();
                } catch (UnknownHostException e) {
                        e.printStackTrace();
@@ -131,8 +131,9 @@ public class Server implements Runnable {
                                                try {
                                                        ss.open(false);
 
-                                                       while (processCmd(ss))
-                                                               ;
+                                                       while (processCmd(ss)) {
+                                                               // nothing to do: process the command
+                                                       }
 
                                                } catch (IOException e) {
                                                        e.printStackTrace();
@@ -185,24 +186,24 @@ public class Server implements Runnable {
         *             in case of IO error
         */
        private boolean processCmd(SimpleSocket s) throws IOException {
-               Command cmd = s.receiveCommand();
-               Command.Verb verb = cmd.getVerb();
+               CommandInstance cmd = s.receiveCommand();
+               Command command = cmd.getCommand();
 
-               if (verb == null)
+               if (command == null)
                        return false;
 
                boolean clientContinue = true;
 
-               System.out.println(s + " ->  " + verb
+               System.out.println(s + " ->  " + command
                                + (cmd.getParam() == null ? "" : " " + cmd.getParam()));
 
-               switch (verb) {
+               switch (command) {
                case STOP: {
                        clientContinue = false;
                        break;
                }
                case VERSION: {
-                       s.sendCommand(Verb.VERSION);
+                       s.sendLine("" + SimpleSocket.CURRENT_VERSION);
                        break;
                }
                case TIME: {
@@ -237,12 +238,13 @@ public class Server implements Runnable {
                                        try {
                                                s.sendLine(StringUtils.fromTime(file.lastModified()));
 
-                                               while (processLockedCmd(s, name))
-                                                       ;
+                                               while (processLockedCmd(s, name)) {
+                                                       // nothing to do: process the command
+                                               }
                                        } catch (InvalidParameterException e) {
                                                System.err
                                                                .println("Unsupported command received from a client connection, closing it: "
-                                                                               + verb + " (" + e.getMessage() + ")");
+                                                                               + command + " (" + e.getMessage() + ")");
                                                clientContinue = false;
                                        }
                                }
@@ -258,10 +260,12 @@ public class Server implements Runnable {
                        }
                        break;
                }
-               case LIST: {
+               case LIST_CARD: {
                        for (File file : dataDir.listFiles()) {
-                               if (cmd.getParam() == null || cmd.getParam().length() == 0
-                                               || file.getName().contains(cmd.getParam())) {
+                               if (cmd.getParam() == null
+                                               || cmd.getParam().length() == 0
+                                               || file.getName().toLowerCase()
+                                                               .contains(cmd.getParam().toLowerCase())) {
                                        s.send(StringUtils.fromTime(file.lastModified()) + " "
                                                        + file.getName());
                                }
@@ -274,15 +278,15 @@ public class Server implements Runnable {
                        s.send("The following commands are available:");
                        s.send("- TIME: get the server time");
                        s.send("- HELP: this help screen");
-                       s.send("- LIST: list the available cards on this server");
-                       s.send("- VERSION/GET/PUT/POST/DELETE/STOP: TODO");
+                       s.send("- LIST_CARD: list the available cards on this server");
+                       s.send("- VERSION/GET_*/PUT_*/POST_*/DELETE_*/STOP: TODO");
                        s.sendBlock();
                        break;
                }
                default: {
                        System.err
                                        .println("Unsupported command received from a client connection, closing it: "
-                                                       + verb);
+                                                       + command);
                        clientContinue = false;
                        break;
                }
@@ -310,19 +314,19 @@ public class Server implements Runnable {
         */
        private boolean processLockedCmd(SimpleSocket s, String name)
                        throws IOException {
-               Command cmd = s.receiveCommand();
-               Command.Verb verb = cmd.getVerb();
+               CommandInstance cmd = s.receiveCommand();
+               Command command = cmd.getCommand();
 
-               if (verb == null)
+               if (command == null)
                        return false;
 
                boolean clientContinue = true;
 
-               System.out.println(s + " ->  " + verb);
+               System.out.println(s + " ->  " + command);
 
-               switch (verb) {
+               switch (command) {
                case GET_CARD: {
-                       s.sendBlock(doGetCard(name));
+                       sendCardBlock(s, name);
                        break;
                }
                case POST_CARD: {
@@ -339,13 +343,15 @@ public class Server implements Runnable {
                        } else {
                                Card card = new Card(vcf, Format.VCard21);
                                try {
-                                       while (processContactCmd(s, card))
-                                               ;
+                                       while (processContactCmd(s, card)) {
+                                               // nothing to do: process the command
+                                       }
                                        card.save();
+                                       s.sendLine(StringUtils.fromTime(card.getLastModified()));
                                } catch (InvalidParameterException e) {
                                        System.err
                                                        .println("Unsupported command received from a client connection, closing it: "
-                                                                       + verb + " (" + e.getMessage() + ")");
+                                                                       + command + " (" + e.getMessage() + ")");
                                        clientContinue = false;
                                }
                        }
@@ -355,7 +361,7 @@ public class Server implements Runnable {
                        // TODO
                        System.err
                                        .println("Unsupported command received from a client connection, closing it: "
-                                                       + verb);
+                                                       + command);
                        clientContinue = false;
                        break;
                }
@@ -364,7 +370,8 @@ public class Server implements Runnable {
                        break;
                }
                default: {
-                       throw new InvalidParameterException("command invalid here");
+                       throw new InvalidParameterException("command invalid here: "
+                                       + command);
                }
                }
 
@@ -389,36 +396,39 @@ public class Server implements Runnable {
         */
        private boolean processContactCmd(SimpleSocket s, Card card)
                        throws IOException {
-               Command cmd = s.receiveCommand();
-               Command.Verb verb = cmd.getVerb();
+               CommandInstance cmd = s.receiveCommand();
+               Command command = cmd.getCommand();
 
-               if (verb == null)
+               if (command == null)
                        return false;
 
                boolean clientContinue = true;
 
-               System.out.println(s + " ->  " + verb);
+               System.out.println(s + " ->  " + command);
 
-               switch (verb) {
+               switch (command) {
                case GET_CONTACT: {
                        Contact contact = card.getById(cmd.getParam());
-                       if (contact != null)
-                               s.sendBlock(Vcard21Parser.toStrings(contact, -1));
-                       else
+                       if (contact != null) {
+                               BlockAppendable app = s.createBlockAppendable();
+                               Vcard21Parser.write(app, contact, -1);
+                               app.close();
+                       } else {
                                s.sendBlock();
+                       }
                        break;
                }
                case POST_CONTACT: {
-                       String uid = cmd.getParam();
-                       Contact contact = card.getById(uid);
-                       if (contact != null)
-                               contact.delete();
                        List<Contact> list = Vcard21Parser.parseContact(s.receiveBlock());
                        if (list.size() > 0) {
-                               contact = list.get(0);
-                               contact.getPreferredData("UID").setValue(uid);
-                               card.add(contact);
+                               Contact newContact = list.get(0);
+                               String uid = newContact.getPreferredDataValue("UID");
+                               Contact oldContact = card.getById(uid);
+                               if (oldContact != null)
+                                       oldContact.delete();
+                               card.add(newContact);
                        }
+
                        break;
                }
                case PUT_CONTACT: {
@@ -428,8 +438,9 @@ public class Server implements Runnable {
                                throw new InvalidParameterException(
                                                "Cannot find contact to modify for UID: " + uid);
                        }
-                       while (processDataCmd(s, contact))
-                               ;
+                       while (processDataCmd(s, contact)) {
+                               // nothing to do: process the command
+                       }
                        break;
                }
                case DELETE_CONTACT: {
@@ -443,12 +454,38 @@ public class Server implements Runnable {
                        contact.delete();
                        break;
                }
+               case HASH_CONTACT: {
+                       String uid = cmd.getParam();
+                       Contact contact = card.getById(uid);
+
+                       if (contact == null) {
+                               s.sendBlock();
+                       } else {
+                               s.sendLine(contact.getContentState(true));
+                       }
+                       break;
+               }
+               case LIST_CONTACT: {
+                       for (Contact contact : card) {
+                               if (cmd.getParam() == null
+                                               || cmd.getParam().length() == 0
+                                               || (contact.getPreferredDataValue("FN") + contact
+                                                               .getPreferredDataValue("N")).toLowerCase()
+                                                               .contains(cmd.getParam().toLowerCase())) {
+                                       s.send(contact.getContentState(true) + " "
+                                                       + contact.getId());
+                               }
+                       }
+                       s.sendBlock();
+                       break;
+               }
                case PUT_CARD: {
                        clientContinue = false;
                        break;
                }
                default: {
-                       throw new InvalidParameterException("command invalid here");
+                       throw new InvalidParameterException("command invalid here: "
+                                       + command);
                }
                }
 
@@ -473,30 +510,33 @@ public class Server implements Runnable {
         */
        private boolean processDataCmd(SimpleSocket s, Contact contact)
                        throws IOException {
-               Command cmd = s.receiveCommand();
-               Command.Verb verb = cmd.getVerb();
+               CommandInstance cmd = s.receiveCommand();
+               Command command = cmd.getCommand();
 
-               if (verb == null)
+               if (command == null)
                        return false;
 
                boolean clientContinue = true;
 
-               System.out.println(s + " ->  " + verb);
+               System.out.println(s + " ->  " + command);
 
-               switch (verb) {
+               switch (command) {
                case GET_DATA: {
-                       Data data = contact.getById(cmd.getParam());
-                       if (data != null)
-                               s.sendBlock(Vcard21Parser.toStrings(data));
-                       else
-                               s.sendBlock();
+                       for (Data data : contact) {
+                               if (data.getName().equals(cmd.getParam())) {
+                                       BlockAppendable app = s.createBlockAppendable();
+                                       Vcard21Parser.write(app, data);
+                                       // note: we do NOT close 'app', since it would send an EOB
+                               }
+                       }
+                       s.sendBlock();
                        break;
                }
                case POST_DATA: {
                        String cstate = cmd.getParam();
                        Data data = null;
                        for (Data d : contact) {
-                               if (cstate.equals(d.getContentState()))
+                               if (cstate.equals(d.getContentState(true)))
                                        data = d;
                        }
 
@@ -512,7 +552,7 @@ public class Server implements Runnable {
                        String cstate = cmd.getParam();
                        Data data = null;
                        for (Data d : contact) {
-                               if (cstate.equals(d.getContentState()))
+                               if (cstate.equals(d.getContentState(true)))
                                        data = d;
                        }
 
@@ -525,12 +565,34 @@ public class Server implements Runnable {
                        contact.delete();
                        break;
                }
+               case HASH_DATA: {
+                       for (Data data : contact) {
+                               if (data.getId().equals(cmd.getParam())) {
+                                       s.send(data.getContentState(true));
+                               }
+                       }
+                       s.sendBlock();
+                       break;
+               }
+               case LIST_DATA: {
+                       for (Data data : contact) {
+                               if (cmd.getParam() == null
+                                               || cmd.getParam().length() == 0
+                                               || data.getName().toLowerCase()
+                                                               .contains(cmd.getParam().toLowerCase())) {
+                                       s.send(data.getContentState(true) + " " + data.getName());
+                               }
+                       }
+                       s.sendBlock();
+                       break;
+               }
                case PUT_CONTACT: {
                        clientContinue = false;
                        break;
                }
                default: {
-                       throw new InvalidParameterException("command invalid here");
+                       throw new InvalidParameterException("command invalid here: "
+                                       + command);
                }
                }
 
@@ -548,20 +610,19 @@ public class Server implements Runnable {
         * @throws IOException
         *             in case of error
         */
-       private List<String> doGetCard(String name) throws IOException {
-               List<String> lines = new LinkedList<String>();
-
+       private void sendCardBlock(SimpleSocket s, String name) throws IOException {
                File vcf = getFile(name);
+               BlockAppendable app = s.createBlockAppendable();
 
                if (vcf != null && vcf.exists()) {
                        Card card = new Card(vcf, Format.VCard21);
 
-                       // timestamp:
-                       lines.add(StringUtils.fromTime(card.getLastModified()));
-                       lines.addAll(Vcard21Parser.toStrings(card));
+                       // timestamp + data
+                       app.append(StringUtils.fromTime(card.getLastModified()) + "\r\n");
+                       Vcard21Parser.write(app, card);
                }
 
-               return lines;
+               app.close();
        }
 
        /**