www.pudn.com > sms.rar > CMainThread.java


//	jSMSEngine API. 
//	An open-source API package for sending and receiving SMS via a GSM device. 
//	Copyright (C) 2002-2006, Thanasis Delenikas, Athens/GREECE 
//		Web Site: http://www.jsmsengine.org 
// 
//	jSMSEngine is a package which can be used in order to add SMS processing 
//		capabilities in an application. jSMSEngine is written in Java. It allows you 
//		to communicate with a compatible mobile phone or GSM Modem, and 
//		send / receive SMS messages. 
// 
//	jSMSEngine is distributed under the LGPL license. 
// 
//	This library is free software; you can redistribute it and/or 
//		modify it under the terms of the GNU Lesser General Public 
//		License as published by the Free Software Foundation; either 
//		version 2.1 of the License, or (at your option) any later version. 
//	This library is distributed in the hope that it will be useful, 
//		but WITHOUT ANY WARRANTY; without even the implied warranty of 
//		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
//		Lesser General Public License for more details. 
//	You should have received a copy of the GNU Lesser General Public 
//		License along with this library; if not, write to the Free Software 
//		Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
// 
 
// 
//	jSMSServer GUI Application. 
//	This application is based on the old jSMSServer GUI, and provides a general purpose 
//		graphical interface. It can be used for a quick-start, if you don't want 
//		to mess around with the API itself. 
//	Please read jSMSServer.txt for further information. 
// 
 
import java.io.*; 
import java.util.*; 
import java.text.*; 
import javax.swing.*; 
 
import javax.xml.parsers.*; 
import org.xml.sax.*; 
import org.xml.sax.helpers.*; 
 
import org.jsmsengine.*; 
 
class CMainThread extends Thread 
{ 
	private jSMSServer jSmsServer; 
	private CSettings settings; 
	private CDatabase database; 
	protected CService service; 
	protected CMainWindow mainWindow; 
 
	private boolean connectRequest; 
	private boolean exitRequest; 
	private boolean exitFinished; 
 
	public CMainThread(jSMSServer jSmsServer, CMainWindow mainWindow, CSettings settings) 
	{ 
		this.jSmsServer = jSmsServer; 
		this.mainWindow = mainWindow; 
		this.settings = settings; 
	} 
 
	public void initialize() 
	{ 
		database = new CDatabase(settings, this); 
		if (mainWindow != null) mainWindow.setConnected(false); 
		exitRequest = false; 
		exitFinished = false; 
		connectRequest = false; 
		start(); 
	} 
 
	public boolean connect(boolean calledFromMenu) 
	{ 
		try 
		{ 
			if (mainWindow == null) System.out.println(CConstants.TEXT_CONNECTING); 
			service = new org.jsmsengine.CService(settings.getSerialDriverSettings().getPort(), settings.getSerialDriverSettings().getBaud(), settings.getPhoneSettings().getManufacturer(), settings.getPhoneSettings().getModel()); 
			if (settings.getPhoneSettings().getPhoneBookFile() != null) service.setPhoneBook(settings.getPhoneSettings().getPhoneBookFile()); 
			service.setSimPin(settings.getPhoneSettings().getSimPin()); 
			service.connect(); 
			service.setSmscNumber(settings.getPhoneSettings().getSmscNumber()); 
			if (mainWindow != null) 
			{ 
				mainWindow.setManufText(service.getDeviceInfo().getManufacturer()); 
				mainWindow.setModelText(service.getDeviceInfo().getModel()); 
				mainWindow.setSerialNoText(service.getDeviceInfo().getSerialNo()); 
				mainWindow.setIMSIText(service.getDeviceInfo().getImsi()); 
				mainWindow.setSwVersionText(service.getDeviceInfo().getSwVersion()); 
				mainWindow.setBatteryIndicator(service.getDeviceInfo().getBatteryLevel()); 
				mainWindow.setSignalIndicator(service.getDeviceInfo().getSignalLevel()); 
				mainWindow.setStatusText(CConstants.STATUS_CONNECTED); 
			} 
			else 
			{ 
				System.out.println(CConstants.TEXT_INFO); 
				System.out.println("\t" + jSmsServer.stripHtml(CConstants.LABEL_MANUFACTURER) + " " + service.getDeviceInfo().getManufacturer()); 
				System.out.println("\t" + jSmsServer.stripHtml(CConstants.LABEL_MODEL) + " " + service.getDeviceInfo().getModel()); 
				System.out.println("\t" + jSmsServer.stripHtml(CConstants.LABEL_SERIALNO) + " " + service.getDeviceInfo().getSerialNo()); 
				System.out.println("\t" + jSmsServer.stripHtml(CConstants.LABEL_IMSI) + " " + service.getDeviceInfo().getImsi()); 
				System.out.println("\t" + jSmsServer.stripHtml(CConstants.LABEL_SWVERSION) + " " + service.getDeviceInfo().getSwVersion()); 
				System.out.println("\t" + jSmsServer.stripHtml(CConstants.LABEL_BATTERY) + " " + service.getDeviceInfo().getBatteryLevel() + "%"); 
				System.out.println("\t" + jSmsServer.stripHtml(CConstants.LABEL_SIGNAL) + " " + service.getDeviceInfo().getSignalLevel() + "%"); 
			} 
			if (settings.getDatabaseSettings().getEnabled()) 
				try { database.open(); } 
				catch (Exception e) 
				{ 
					if (mainWindow != null) JOptionPane.showMessageDialog(mainWindow, CConstants.ERROR_CANNOT_OPEN_DATABASE, CConstants.ERROR_TITLE, JOptionPane.ERROR_MESSAGE); 
					else System.out.println(CConstants.ERROR_TITLE + " " + CConstants.ERROR_CANNOT_OPEN_DATABASE);				 
					database.close(); 
				} 
			if (mainWindow != null) mainWindow.setConnected(true); 
			else System.out.println(CConstants.LABEL_STATUS + CConstants.STATUS_CONNECTED); 
			if (calledFromMenu) connectRequest = true; 
			return true; 
		} 
		catch (CannotDisableIndicationsException e) 
		{ 
			if (!connectRequest) 
			{ 
				if (mainWindow != null) JOptionPane.showMessageDialog(mainWindow, CConstants.ERROR_CANNOT_DISABLE_INDICATIONS, CConstants.ERROR_TITLE, JOptionPane.ERROR_MESSAGE); 
				else System.out.println(CConstants.ERROR_TITLE + " " + CConstants.ERROR_CANNOT_DISABLE_INDICATIONS); 
			} 
			disconnect(false); 
			return false; 
		} 
		catch (InvalidPinException e) 
		{ 
			if (!connectRequest)  
			{ 
				if (mainWindow != null) JOptionPane.showMessageDialog(mainWindow, CConstants.ERROR_INVALID_PIN, CConstants.ERROR_TITLE, JOptionPane.ERROR_MESSAGE); 
				else System.out.println(CConstants.ERROR_TITLE + " " + CConstants.ERROR_INVALID_PIN); 
			} 
			disconnect(false); 
			return false; 
		} 
		catch (NoPinException e) 
		{ 
			if (!connectRequest)  
			{ 
				if (mainWindow != null) JOptionPane.showMessageDialog(mainWindow, CConstants.ERROR_NO_PIN, CConstants.ERROR_TITLE, JOptionPane.ERROR_MESSAGE); 
				else System.out.println(CConstants.ERROR_TITLE + " " + CConstants.ERROR_NO_PIN); 
			} 
			disconnect(false); 
			return false; 
		} 
		catch (NoPduSupportException e) 
		{ 
			if (!connectRequest)  
			{ 
				if (mainWindow != null) JOptionPane.showMessageDialog(mainWindow, CConstants.ERROR_NO_PDU_SUPPORT, CConstants.ERROR_TITLE, JOptionPane.ERROR_MESSAGE); 
				else System.out.println(CConstants.ERROR_TITLE + " " + CConstants.ERROR_NO_PDU_SUPPORT); 
			} 
			disconnect(false); 
			return false; 
		} 
		catch (NotConnectedException e) 
		{ 
			if (!connectRequest)  
			{ 
				if (mainWindow != null) JOptionPane.showMessageDialog(mainWindow, CConstants.ERROR_CANNOT_CONNECT + "\n" + e.getMessage(), CConstants.ERROR_TITLE, JOptionPane.ERROR_MESSAGE); 
				else System.out.println(CConstants.ERROR_TITLE + " " + CConstants.ERROR_CANNOT_CONNECT + e.getMessage()); 
			} 
			disconnect(false); 
			return false; 
		} 
		catch (Exception e) 
		{ 
			if (!connectRequest) 
			{ 
				if (mainWindow != null) JOptionPane.showMessageDialog(mainWindow, CConstants.ERROR_CANNOT_CONNECT + "\n" + e.getMessage(), CConstants.ERROR_TITLE, JOptionPane.ERROR_MESSAGE); 
				else 
				{ 
					System.out.println(CConstants.ERROR_TITLE + " " + CConstants.ERROR_CANNOT_CONNECT + e.getMessage()); 
					e.printStackTrace(); 
				} 
			} 
			disconnect(false); 
			return false; 
		} 
	} 
 
	public void disconnect(boolean calledFromMenu) 
	{ 
		service.disconnect(); 
		if (settings.getDatabaseSettings().getEnabled()) database.close(); 
		if (mainWindow != null) mainWindow.setConnected(false); 
		else System.out.println(CConstants.LABEL_STATUS + CConstants.STATUS_DISCONNECTED); 
		if (calledFromMenu) connectRequest = false; 
	} 
 
	public boolean processMessage(CIncomingMessage message) throws Exception 
	{ 
		if (mainWindow != null) 
		{ 
			mainWindow.setInFrom(message.getOriginator()); 
			mainWindow.setInDate(message.getDate() != null ? message.getDate().toString() : "* N/A *"); 
			mainWindow.setInText(message.getText()); 
		} 
		else 
		{ 
			System.out.println(CConstants.TEXT_INMSG); 
			System.out.println("\t" + CConstants.LABEL_INCOMING_FROM + message.getOriginator()); 
			System.out.println("\t" + CConstants.LABEL_INCOMING_DATE + message.getDate()); 
			System.out.println("\t" + CConstants.LABEL_INCOMING_TEXT + message.getText()); 
		} 
		settings.getGeneralSettings().rawInLog(message); 
		if (settings.getPhoneSettings().getXmlInQueue() != null) try { saveToXmlInQueue(message); } catch (Exception e) { e.printStackTrace(); } 
		if (settings.getPhoneSettings().getForwardNumber() != null) try { saveToXmlOutQueue(message); } catch (Exception e) { e.printStackTrace(); } 
		if (database.isOpen()) try { database.saveMessage(message); } catch (Exception e) {e.printStackTrace();} 
		return true; 
	} 
 
	public void run() 
	{ 
		boolean proceed; 
 
		while (!exitRequest) 
		{ 
			try { sleep (settings.getPhoneSettings().getPeriodInterval()); } catch (Exception e) {} 
			proceed = false; 
			if (!exitRequest) 
			{ 
				if (service != null) 
				{ 
					if (service.getConnected()) proceed = true; 
					else 
						if (connectRequest) 
						{ 
							disconnect(false); 
							proceed = connect(false); 
						} 
					if (proceed) 
					{ 
						try 
						{ 
							if (mainWindow != null) mainWindow.setStatusText(CConstants.STATUS_REFRESHING); 
							else System.out.println(CConstants.LABEL_STATUS + CConstants.STATUS_REFRESHING); 
							service.refreshDeviceInfo(); 
							if (mainWindow != null) mainWindow.setStatusText(CConstants.STATUS_PROCESS_IN); 
							else System.out.println(CConstants.LABEL_STATUS + CConstants.STATUS_PROCESS_IN); 
							processStoredMessages(); 
							if (mainWindow != null) mainWindow.setStatusText(CConstants.STATUS_PROCESS_OUT); 
							else System.out.println(CConstants.LABEL_STATUS + CConstants.STATUS_PROCESS_OUT); 
							if (settings.getPhoneSettings().getXmlOutQueue() != null) try { checkXmlOutQueue(); } catch (Exception e) { e.printStackTrace(); } 
							if (database.isOpen()) try { database.checkForOutgoingMessages(); } catch (Exception e) { e.printStackTrace(); } 
							if (mainWindow != null) 
							{ 
								mainWindow.setTrafficIn(service.getDeviceInfo().getStatistics().getTotalIn()); 
								mainWindow.setTrafficOut(service.getDeviceInfo().getStatistics().getTotalOut()); 
							} 
							else 
							{ 
								System.out.println(CConstants.LABEL_TRAFFIC + " " + CConstants.LABEL_TRAFFIC_IN + service.getDeviceInfo().getStatistics().getTotalIn() + "   " + CConstants.LABEL_TRAFFIC_OUT + service.getDeviceInfo().getStatistics().getTotalOut()); 
							} 
							if (mainWindow != null) mainWindow.setStatusText(CConstants.STATUS_IDLE); 
							else System.out.println(CConstants.LABEL_STATUS + CConstants.STATUS_IDLE); 
						} 
						catch (Exception e) 
						{ 
							disconnect(false); 
						} 
					} 
				} 
			} 
		} 
		disconnect(false); 
		exitFinished = true;		 
	} 
 
	public void exitRequest() { exitRequest = true; interrupt(); } 
	public boolean exitFinished() { return exitFinished; } 
 
	protected void sendMessage(COutgoingMessage message) throws Exception 
	{ 
		service.sendMessage(message); 
		settings.getGeneralSettings().rawOutLog(message); 
		database.saveSentMessage(message); 
		if (mainWindow != null) 
		{ 
			mainWindow.setOutTo(message.getRecipient()); 
			mainWindow.setOutDate(message.getDispatchDate().toString()); 
			mainWindow.setOutText(message.getText()); 
		} 
		else 
		{ 
			System.out.println(CConstants.TEXT_OUTMSG); 
			System.out.println("\t" + CConstants.LABEL_OUTGOING_TO + message.getRecipient()); 
			System.out.println("\t" + CConstants.LABEL_OUTGOING_DATE + message.getDate()); 
			System.out.println("\t" + CConstants.LABEL_OUTGOING_TEXT + message.getText()); 
		} 
	} 
 
	private synchronized void processStoredMessages() throws Exception 
	{ 
		LinkedList messageList; 
		int batchLimit; 
 
		batchLimit = settings.getPhoneSettings().getBatchIncoming(); 
		messageList = new LinkedList(); 
		service.readMessages(messageList, CIncomingMessage.CLASS_ALL); 
		for (int i = 0; i < messageList.size(); i ++) 
		{ 
			if ((i + 1) > batchLimit) break; 
			CIncomingMessage message = (CIncomingMessage) messageList.get(i); 
			if ((processMessage(message)) && (settings.getPhoneSettings().getDeleteAfterProcessing())) service.deleteMessage(message); 
		} 
	} 
 
	private void saveToXmlInQueue(CIncomingMessage message) throws Exception 
	{ 
		File xmlFile; 
		PrintWriter out; 
 
		xmlFile = File.createTempFile("Recv", ".xml", new File(settings.getPhoneSettings().getXmlInQueue())); 
		out = new PrintWriter(new FileWriter(xmlFile.getCanonicalPath())); 
		out.println(""); 
		out.println(""); 
		out.println("	" + message.getOriginator() + ""); 
		out.println("	" + textDate(message.getDate(), true) + ""); 
		out.println("	  "); 
		out.println(""); 
		out.close(); 
	} 
 
	private void saveToXmlOutQueue(CIncomingMessage message) throws Exception 
	{ 
		File xmlFile; 
		PrintWriter out; 
 
		xmlFile = File.createTempFile("Fwd", ".xml", new File(settings.getPhoneSettings().getXmlOutQueue())); 
		out = new PrintWriter(new FileWriter(xmlFile.getCanonicalPath())); 
		out.println(""); 
		out.println(""); 
		out.println("	" + settings.getPhoneSettings().getForwardNumber() + ""); 
		out.println("	  "); 
		out.println(""); 
		out.close(); 
	} 
 
	private String textDate(java.util.Date date, boolean includeTime) 
	{ 
		String dateStr = ""; 
		Calendar calendar = Calendar.getInstance(); 
		String day, month, year, hour, min, sec; 
 
		if (date == null) return "* N/A *"; 
		calendar.setTime(date); 
		day = "" + calendar.get(Calendar.DAY_OF_MONTH); if (day.length() != 2) day = "0" + day; 
		month = "" + (calendar.get(Calendar.MONTH) + 1); if (month.length() != 2) month = "0" + month; 
		year = "" + calendar.get(Calendar.YEAR); 
		hour = "" + calendar.get(Calendar.HOUR_OF_DAY); if (hour.length() != 2) hour = "0" + hour; 
		min = "" + calendar.get(Calendar.MINUTE); if (min.length() != 2) min = "0" + min; 
		sec = "" + calendar.get(Calendar.SECOND); if (sec.length() != 2) sec = "0" + sec; 
		dateStr = year + "/" + month + "/" + day; 
		if (includeTime) dateStr += " " + hour + ":" + min + ":" + sec; 
		return dateStr; 
	} 
 
	private void checkXmlOutQueue() throws Exception 
	{ 
		COutgoingMessage message; 
		LinkedList messageList; 
		File outDir; 
		File[] files; 
		int result; 
		int batchLimit; 
 
		batchLimit = settings.getPhoneSettings().getBatchOutgoing(); 
		outDir = new File(settings.getPhoneSettings().getXmlOutQueue()); 
		files = outDir.listFiles(new CXmlInFilter()); 
		if (files.length > 0) 
		{ 
			messageList = new LinkedList(); 
			for (int i = 0; i < files.length; i ++) 
			{ 
				if ((i + 1) > batchLimit) break; 
				message = new COutgoingMessage(); 
				try { parseXmlMessageFile(message, files[i].toString()); } catch (Exception e) { e.printStackTrace(); message = null; } 
				if (message != null)  
				{ 
					message.setId(files[i].toString()); 
					if (settings.getPhoneSettings().getMessageEncoding().equalsIgnoreCase("7bit")) message.setMessageEncoding(CMessage.MESSAGE_ENCODING_7BIT); 
					else if (settings.getPhoneSettings().getMessageEncoding().equalsIgnoreCase("8bit")) message.setMessageEncoding(CMessage.MESSAGE_ENCODING_8BIT); 
					else if (settings.getPhoneSettings().getMessageEncoding().equalsIgnoreCase("unicode")) message.setMessageEncoding(CMessage.MESSAGE_ENCODING_UNICODE); 
					else message.setMessageEncoding(CMessage.MESSAGE_ENCODING_7BIT); 
					messageList.add(message); 
				} 
			}  
			service.sendMessage(messageList); 
			for (int i = 0; i < messageList.size(); i ++) 
			{ 
				message = (COutgoingMessage) messageList.get(i); 
				if (message.getDispatchDate() != null) 
				{ 
					settings.getGeneralSettings().rawOutLog(message); 
					if (mainWindow != null) 
					{ 
						mainWindow.setOutTo(message.getRecipient()); 
						mainWindow.setOutDate(message.getDispatchDate().toString()); 
						mainWindow.setOutText(message.getText()); 
					} 
					else 
					{ 
						System.out.println(CConstants.TEXT_OUTMSG); 
						System.out.println("\t" + CConstants.LABEL_OUTGOING_TO + message.getRecipient()); 
						System.out.println("\t" + CConstants.LABEL_OUTGOING_DATE + message.getDate()); 
						System.out.println("\t" + CConstants.LABEL_OUTGOING_TEXT + message.getText()); 
					} 
					File file = new File(message.getId()); 
					file.delete(); 
				} 
			} 
		} 
	} 
 
	private void parseXmlMessageFile(COutgoingMessage message, String file) throws Exception 
	{ 
		SAXParserFactory factory; 
		SAXParser parser; 
		CXMLMessageParser myParser;  
 
		factory = SAXParserFactory.newInstance(); 
		parser = factory.newSAXParser(); 
		myParser = new CXMLMessageParser(); 
		myParser.setMessage(message); 
		parser.parse(new File(file), myParser); 
	} 
 
	class CXmlInFilter implements FilenameFilter 
	{ 
		public boolean accept(File dir, String name) { return name.endsWith(".xml"); } 
	} 
  
	class CXMLMessageParser extends DefaultHandler 
	{ 
		String level = ""; 
		String info = ""; 
		COutgoingMessage message = null; 
 
		public void setMessage(COutgoingMessage message) { this.message = message; } 
 
		public void startElement (String uri, String lName, String qName, Attributes attrs) throws SAXException 
		{ 
			level = level + "/" + qName; 
			info = ""; 
		} 
 
		public void endElement (String uri, String lName, String qName) throws SAXException 
		{ 
			if (level.equalsIgnoreCase("/message/recipient")) message.setRecipient(info.trim()); 
			if (level.equalsIgnoreCase("/message/text")) message.setText(info.trim()); 
			level = level.substring(0, level.lastIndexOf("/")); 
		} 
 
		public void characters (char buf [], int offset, int len) throws SAXException 
		{ 
			String token; 
 
			token = new String(buf, offset, len).trim(); 
			if (token.length() == 0) return; 
			info = info + token; 
		} 
	} 
}