/* Program som implementerar uppgift 3A men som följer ett xml dokument! */ import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.util.*; import java.net.*; import java.io.*; import org.jdom.*; import org.jdom.input.*; import org.jdom.output.*; public class XmlClient extends JFrame{ private JTextField inputField = new JTextField(20); private JTextField namefield = new JTextField(20); private JTextField userfield = new JTextField(20); private JTextArea textarea = new JTextArea(); //datautström & readström för K - S private DataOutputStream outStream; private ReadStream read; private Socket clientSocket; public XmlClient(String[] args){ String host="192.168.0.189"; int port=2000; if (args.length==1) host=args[0]; else if (args.length==2){ host=args[0]; int portNo=Integer.parseInt(args[1]); if (portNo>1023 && portNo<65536){ port=portNo; } } //lyssnare för att stänga hela strömmen!! addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ try{ outStream.close(); clientSocket.close(); }catch(IOException ioex){} read.setOffline(); System.exit(0); }}); addKeyListener(new EnterListener()); setTitle("Xml chatter"); setSize(640, 480); JPanel inputBar = new JPanel(); JButton sendButton = new JButton("Skicka"); sendButton.addActionListener(new SendListener()); inputBar.add(inputField); inputBar.add(sendButton); getContentPane().add(inputBar, BorderLayout.NORTH); JScrollPane scrolly = new JScrollPane(textarea); getContentPane().add(scrolly, BorderLayout.CENTER); JPanel userBar = new JPanel(); userBar.add(new JLabel("User name:")); userBar.add(namefield); userBar.add(new JLabel("E-mail adress:")); userBar.add(userfield); getContentPane().add(userBar, BorderLayout.SOUTH); show(); connect(host, port); } //exakt samma kod som 3a protected void connect(String urlAdress, int port){ try{ clientSocket = new Socket(urlAdress, port); outStream = new DataOutputStream(clientSocket.getOutputStream()); read = new ReadStream(new BufferedReader(new InputStreamReader(clientSocket.getInputStream())), this); read.start(); }catch(UnknownHostException uhe){ System.out.println("Host unknown!"); System.exit(0); }catch(IOException ioe){ System.out.println("Server offline!"); System.exit(0); } title("Connected to server: "+urlAdress+":"+port); } protected void title(String message){ //sätt medd i status bar överst setTitle(message); } protected void logg(String message){ //radbyte! if(!message.endsWith("\n")) message=message+"\n"; textarea.append(message); textarea.setCaretPosition(textarea.getText().length()); } protected void sendStream(){ try{ if(inputField.getText().trim().length()>0){ //hämta doctypen, skapa xmlparsern Document doc = getXMLMessage(); XMLOutputter xmlop = new XMLOutputter(); String message = xmlop.outputString(doc); //fade to black StringTokenizer tok = new StringTokenizer(message, "\n,\r"); message=""; while(tok.hasMoreTokens()){ message+=tok.nextToken(); } //skriv meddelandet outStream.writeBytes(message+"\n"); } inputField.setText(""); inputField.requestFocus(); }catch(IOException ioe){ } } protected Document getXMLMessage(){ //skapa elementen och lägg i xml filen: Element message = new Element("message"); Document doc = new Document(message); Element header = new Element("header"); message.addContent(header); Element protocol = new Element("protocol"); Element id = new Element("id"); header.addContent(protocol); header.addContent(id); Element type = new Element("type").setText("CTTP"); Element version = new Element("version").setText("1.0"); Element command = new Element("command").setText("MESS"); protocol.addContent(type); protocol.addContent(version); protocol.addContent(command); Element name = new Element("name"); Element email = new Element("email"); Element homepage = new Element("homepage").setText("www.aik.se"); Element host = new Element("host").setText("unknown"); name.setText(namefield.getText()); email.setText(userfield.getText()); id.addContent(name); id.addContent(email); id.addContent(homepage); id.addContent(host); Element body = new Element("body"); body.setText(inputField.getText().trim()); message.addContent(body); DocType docType = new DocType("message"); docType.setSystemID("http://atlas.dsv.su.se/~pierre/i/ip1/inl/i5/message.dtd"); doc.setDocType(docType); return doc; } protected class ReadStream extends Thread{ private XmlClient chcl; private BufferedReader input; //läsa inström private String line=""; private boolean online = true; public ReadStream(BufferedReader inputStream, XmlClient client){ chcl=client; input=inputStream; } public void setOffline(){ try{ input.close(); }catch(IOException e){} online=false; } //skicka xml meddelandet!!! protected String parseMessage(String message){ try{ SAXBuilder builder = new SAXBuilder(true); Document doc = builder.build(new StringReader(message)); Element root = doc.getRootElement(); String body = root.getChild("body").getText(); Element id = root.getChild("header").getChild("id"); String user = id.getChild("name").getText(); String email = id.getChild("email").getText(); return user+" ("+email+"): "+body; }catch(JDOMException jdome){ } return "Message parsing error"; } //som 3a public void run(){ while(online){ try{ sleep(1000); if((line=input.readLine())!=null){ String message = parseMessage(line); chcl.logg(message+"\n"); } }catch(InterruptedException e){ }catch(IOException ioe){ chcl.title("not connected"); } } } } //lyssnarna samma som i 3a class SendListener implements ActionListener{ public void actionPerformed(ActionEvent e){ sendStream(); } } class EnterListener extends KeyAdapter{ public void keyPressed(KeyEvent e){ int key = e.getKeyCode(); if (key==e.VK_ENTER){ if(inputField.hasFocus()){ sendStream(); inputField.setText(""); inputField.requestFocus(); } } } } public static void main(String[] args){ new XmlClient(args); } }