package com.almalence.sony.cameraremote; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import android.util.Log; import com.almalence.sony.cameraremote.utils.SimpleHttpClient; import com.almalence.sony.cameraremote.utils.XmlElement; /** * A server device description class. */ public final class ServerDevice { private static final String TAG = ServerDevice.class.getSimpleName(); /** * Camera Remote API service (category). For example, "camera", "guide" and * so on. "Action List URL" is API request target URL of each service. */ public static class ApiService { private String mName; private String mActionListUrl; /** * Constructor * * @param name category name * @param actionListUrl action list URL of the category */ public ApiService(String name, String actionListUrl) { mName = name; mActionListUrl = actionListUrl; } /** * Returns the category name. * * @return category name. */ public String getName() { return mName; } /** * Sets a category name. * * @param name category name */ public void setName(String name) { this.mName = name; } /** * Returns the action list URL of the category. * * @return action list URL */ public String getActionListUrl() { return mActionListUrl; } /** * Sets an action list URL of the category. * * @param actionListUrl action list URL of the category */ public void setActionListUrl(String actionListUrl) { this.mActionListUrl = actionListUrl; } /** * Returns the endpoint URL of the category. * * @return endpoint URL */ public String getEndpointUrl() { String url = null; if (mActionListUrl == null || mName == null) { url = null; } else if (mActionListUrl.endsWith("/")) { url = mActionListUrl + mName; } else { url = mActionListUrl + "/" + mName; } return url; } } private String mDDUrl; private String mFriendlyName; private String mModelName; private String mUDN; private String mIconUrl; private final List<ApiService> mApiServices; private ServerDevice() { mApiServices = new ArrayList<ServerDevice.ApiService>(); } /** * Returns URL of Device Description XML * * @return URL string */ public String getDDUrl() { return mDDUrl; } /** * Returns a value of friendlyName in DD. * * @return friendlyName */ public String getFriendlyName() { return mFriendlyName; } /** * Returns a value of modelName in DD. * * @return modelName */ public String getModelName() { return mModelName; } /** * Returns a value of UDN in DD. * * @return UDN */ public String getUDN() { return mUDN; } /** * Returns URL of icon in DD. * * @return URL of icon */ public String getIconUrl() { return mIconUrl; } /** * Returns IP address of the DD. * * @return IP address */ public String getIpAddres() { String ip = null; if (mDDUrl != null) { return toHost(mDDUrl); } return ip; } /** * Returns a list of categories that the server supports. * * @return a list of categories */ public List<ApiService> getApiServices() { return Collections.unmodifiableList(mApiServices); } /** * Checks to see whether the server supports the category. * * @param serviceName category name * @return true if it's supported. */ public boolean hasApiService(String serviceName) { if (serviceName == null) { return false; } for (ApiService apiService : mApiServices) { if (serviceName.equals(apiService.getName())) { return true; } } return false; } /** * Returns a ApiService object. * * @param serviceName category name * @return ApiService object */ public ApiService getApiService(String serviceName) { if (serviceName == null) { return null; } for (ApiService apiService : mApiServices) { if (serviceName.equals(apiService.getName())) { return apiService; } } return null; } /** * Adds a ApiService object. * * @param name * @param actionUrl */ private void addApiService(String name, String actionUrl) { ApiService service = new ApiService(name, actionUrl); mApiServices.add(service); } /** * Fetches device description xml file from server and parses it. * * @param ddUrl URL of device description xml. * @return ServerDevice instance */ public static ServerDevice fetch(String ddUrl) { if (ddUrl == null) { throw new NullPointerException("ddUrl is null."); } String ddXml = ""; try { ddXml = SimpleHttpClient.httpGet(ddUrl); Log.d(TAG, "fetch () httpGet done."); } catch (IOException e) { Log.e(TAG, "fetch: IOException.", e); return null; } XmlElement rootElement = XmlElement.parse(ddXml); // "root" ServerDevice device = null; if ("root".equals(rootElement.getTagName())) { device = new ServerDevice(); device.mDDUrl = ddUrl; // "device" XmlElement deviceElement = rootElement.findChild("device"); device.mFriendlyName = deviceElement.findChild("friendlyName").getValue(); device.mModelName = deviceElement.findChild("modelName").getValue(); device.mUDN = deviceElement.findChild("UDN").getValue(); // "iconList" XmlElement iconListElement = deviceElement.findChild("iconList"); List<XmlElement> iconElements = iconListElement.findChildren("icon"); for (XmlElement iconElement : iconElements) { // Choose png icon to show Android UI. if ("image/png".equals(iconElement.findChild("mimetype").getValue())) { String uri = iconElement.findChild("url").getValue(); String hostUrl = toSchemeAndHost(ddUrl); device.mIconUrl = hostUrl + uri; } } // "av:X_ScalarWebAPI_DeviceInfo" XmlElement wApiElement = deviceElement.findChild("X_ScalarWebAPI_DeviceInfo"); XmlElement wApiServiceListElement = wApiElement.findChild("X_ScalarWebAPI_ServiceList"); List<XmlElement> wApiServiceElements = wApiServiceListElement .findChildren("X_ScalarWebAPI_Service"); for (XmlElement wApiServiceElement : wApiServiceElements) { String serviceName = wApiServiceElement.findChild("X_ScalarWebAPI_ServiceType") .getValue(); String actionUrl = wApiServiceElement.findChild("X_ScalarWebAPI_ActionList_URL") .getValue(); device.addApiService(serviceName, actionUrl); } } Log.d(TAG, "fetch () parsing XML done."); return device; } private static String toSchemeAndHost(String url) { int i = url.indexOf("://"); // http:// or https:// if (i == -1) { return ""; } int j = url.indexOf("/", i + 3); if (j == -1) { return ""; } String hostUrl = url.substring(0, j); return hostUrl; } private static String toHost(String url) { int i = url.indexOf("://"); // http:// or https:// if (i == -1) { return ""; } int j = url.indexOf(":", i + 3); if (j == -1) { return ""; } String host = url.substring(i + 3, j); return host; } }