package com.snda.mzang.tvtogether.utils.comm; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.snda.mzang.tvtogether.base.JSONUtil; import com.snda.mzang.tvtogether.exceptions.InvalidatedClientDataException; import com.snda.mzang.tvtogether.exceptions.InvalidatedServerDataException; import com.snda.mzang.tvtogether.utils.C; import com.snda.mzang.tvtogether.utils.UserSession; public class ServerCommMock implements IServerComm { private Map<String, IMessageHandler> handlers = new HashMap<String, IMessageHandler>(); public ServerCommMock() { IMessageHandler handler = new LoginHandlerMockup(); handlers.put(handler.getHandlerName(), handler); handler = new GetChannelListHandlerMockup(); handlers.put(handler.getHandlerName(), handler); handler = new GetServerResourceMockup(); handlers.put(handler.getHandlerName(), handler); } public JSONObject sendMsg(JSONObject msg) { return sendMsg(msg, C.jsonc); } public <T> T sendMsg(JSONObject msg, IContentConverter<T> converter) { if (msg == null) { throw new InvalidatedClientDataException("Message is null"); } if (msg.has(C.processor) == false) { throw new InvalidatedClientDataException("Message has no handler"); } try { msg.put(C.username, UserSession.getUserName()); msg.put(C.password, UserSession.getPassword()); } catch (JSONException e1) { throw new InvalidatedClientDataException(); } String handlerName = null; try { handlerName = (String) msg.get(C.processor); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return sendMsg(handlerName, msg.toString().getBytes(), converter); } @SuppressWarnings("unchecked") public <T> T sendMsg(String handlerName, byte[] message, IContentConverter<T> converter) { try { IMessageHandler handler = handlers.get(handlerName); if (handler == null) { throw new InvalidatedServerDataException("No handler found for name \"" + handlerName + "\""); } try { // mock waiting :) Thread.sleep(100); } catch (InterruptedException e) { } byte[] serverContent = handler.handle(message); if (converter == null) { return (T) serverContent; } return converter.convert(serverContent); } catch (JSONException e) { throw new InvalidatedClientDataException(e); } catch (Exception e) { throw new InvalidatedServerDataException(e); } } interface IMessageHandler { String getHandlerName(); byte[] handle(byte[] message); } abstract class BaseJSONMessageHandler implements IMessageHandler { public byte[] handle(byte[] message) { String jsonStr = new String(message); JSONObject json = null; try { json = new JSONObject(jsonStr); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return handle(json); } public abstract byte[] handle(JSONObject message); } class LoginHandlerMockup extends BaseJSONMessageHandler { public String getHandlerName() { return C.login; } public byte[] handle(JSONObject msg) { JSONObject ret = new JSONObject(); try { ret.put(C.result, C.success); } catch (JSONException e) { e.printStackTrace(); } return ret.toString().getBytes(); } } private static Map<String, byte[]> cache = new HashMap<String, byte[]>(); private static String[] channelNames = null; private static String[] loadChannelInfos(String oneRes) { if (channelNames != null) { return channelNames; } try { String imageRoot = C.CHANNEL_RES_LOCAL_DIR; File dir = new File(imageRoot); if (dir.exists() == false || dir.isDirectory() == false) { dir.mkdirs(); } URL url = GetChannelListHandlerMockup.class.getClassLoader().getResource(oneRes); String path = url.getPath(); String jarFilePath = path.substring(path.indexOf('/'), path.indexOf('!')); List<String> resName = new ArrayList<String>(); JarFile file = new JarFile(jarFilePath); Enumeration<JarEntry> ets = file.entries(); String imageDir = oneRes.substring(0, oneRes.lastIndexOf('/') + 1); while (ets.hasMoreElements() == true) { JarEntry jarEntry = ets.nextElement(); String jarEntryPath = jarEntry.getName(); if (jarEntryPath.startsWith(imageDir) == false) { continue; } InputStream input = file.getInputStream(jarEntry); String imgFileName = jarEntryPath.substring(jarEntryPath.lastIndexOf('/') + 1, jarEntryPath.lastIndexOf('.')); resName.add(imgFileName); File dataFile = new File(dir, imgFileName); if (dataFile.exists() == false || dataFile.isFile() == false) { dataFile.createNewFile(); } OutputStream os = new FileOutputStream(dataFile); byte[] buffer = new byte[1024]; int len = -1; while ((len = input.read(buffer)) != -1) { os.write(buffer, 0, len); } input.close(); os.close(); } channelNames = resName.toArray(new String[0]); // BitmapFactory.decodeFile() for (int i = 0; i < resName.size(); i++) { String filePath = imageRoot + resName.get(i); File f = new File(filePath); int len = (int) f.length(); byte[] fileData = new byte[len]; InputStream input = new FileInputStream(f); input.read(fileData); cache.put(filePath, fileData); } return channelNames; } catch (IOException e) { e.printStackTrace(); return null; } } class GetChannelListHandlerMockup extends BaseJSONMessageHandler { public String getHandlerName() { return C.getChannelList; } public byte[] handle(JSONObject msg) { JSONObject ret = new JSONObject(); try { String[] channelNames = loadChannelInfos("com/snda/mzang/tvtogether/res/吉林电视台.png"); ret.put(C.result, C.success); JSONArray channels = new JSONArray(); for (String channelName : channelNames) { channels.put(channelName); } ret.put(C.channels, channels); } catch (JSONException e) { e.printStackTrace(); } return ret.toString().getBytes(); } } class GetServerResourceMockup extends BaseJSONMessageHandler { public String getHandlerName() { return C.getServerResource; } public byte[] handle(JSONObject msg) { String resourceName = JSONUtil.getString(msg, C.resPathOnServ); return cache.get(C.sdroot + resourceName); } } }