/*
* Copyright (c) 2005 Aetrion LLC.
*/
package com.flickr4java.flickr.reflection;
import com.flickr4java.flickr.FlickrException;
import com.flickr4java.flickr.Response;
import com.flickr4java.flickr.Transport;
import com.flickr4java.flickr.util.XMLUtilities;
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Interface for testing the complete implementation of all Flickr-methods.
* <p>
*
* @author Anthony Eden
* @version $Id: ReflectionInterface.java,v 1.10 2008/01/28 23:01:45 x-mago Exp $
*/
public class ReflectionInterface {
private static Logger _log = Logger.getLogger(ReflectionInterface.class);
public static final String METHOD_GET_METHOD_INFO = "flickr.reflection.getMethodInfo";
public static final String METHOD_GET_METHODS = "flickr.reflection.getMethods";
private final String apiKey;
private final String sharedSecret;
private final Transport transport;
/**
* Construct a ReflectionInterface.
*
* @param apiKey
* The API key
* @param sharedSecret
* The Shared Secret
* @param transport
* The Transport interface
*/
public ReflectionInterface(String apiKey, String sharedSecret, Transport transport) {
this.apiKey = apiKey;
this.sharedSecret = sharedSecret;
this.transport = transport;
}
/**
* Get the info for the specified method.
*
* @param methodName
* The method name
* @return The Method object
* @throws FlickrException
*/
public Method getMethodInfo(String methodName) throws FlickrException {
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("method", METHOD_GET_METHOD_INFO);
parameters.put("method_name", methodName);
Response response = transport.get(transport.getPath(), parameters, apiKey, sharedSecret);
if (response.isError()) {
throw new FlickrException(response.getErrorCode(), response.getErrorMessage());
}
Element methodElement = response.getPayload();
Method method = new Method();
method.setName(methodElement.getAttribute("name"));
method.setNeedsLogin("1".equals(methodElement.getAttribute("needslogin")));
method.setNeedsSigning("1".equals(methodElement.getAttribute("needssigning")));
String requiredPermsStr = methodElement.getAttribute("requiredperms");
if (requiredPermsStr != null && requiredPermsStr.length() > 0) {
try {
int perms = Integer.parseInt(requiredPermsStr);
method.setRequiredPerms(perms);
} catch (NumberFormatException e) {
// what shall we do?
e.printStackTrace();
}
}
method.setDescription(XMLUtilities.getChildValue(methodElement, "description"));
method.setResponse(XMLUtilities.getChildValue(methodElement, "response"));
method.setExplanation(XMLUtilities.getChildValue(methodElement, "explanation"));
List<Argument> arguments = new ArrayList<Argument>();
Element argumentsElement = XMLUtilities.getChild(methodElement, "arguments");
// tolerant fix for incorrect nesting of the <arguments> element
// as observed in current flickr responses of this method
//
// specified as
// <rsp>
// <method>
// <arguments>
// <errors>
// <method>
// </rsp>
//
// observed as
// <rsp>
// <method>
// <arguments>
// <errors>
// </rsp>
//
if (argumentsElement == null) {
_log.debug("getMethodInfo: Using workaround for arguments array");
Element parent = (Element) methodElement.getParentNode();
Element child = XMLUtilities.getChild(parent, "arguments");
if (child != null) {
argumentsElement = child;
}
}
NodeList argumentElements = argumentsElement.getElementsByTagName("argument");
for (int i = 0; i < argumentElements.getLength(); i++) {
Argument argument = new Argument();
Element argumentElement = (Element) argumentElements.item(i);
argument.setName(argumentElement.getAttribute("name"));
argument.setOptional("1".equals(argumentElement.getAttribute("optional")));
argument.setDescription(XMLUtilities.getValue(argumentElement));
arguments.add(argument);
}
method.setArguments(arguments);
Element errorsElement = XMLUtilities.getChild(methodElement, "errors");
// tolerant fix for incorrect nesting of the <errors> element
// as observed in current flickr responses of this method
// as of 2006-09-15
//
// specified as
// <rsp>
// <method>
// <arguments>
// <errors>
// <method>
// </rsp>
//
// observed as
// <rsp>
// <method>
// <arguments>
// <errors>
// </rsp>
//
if (errorsElement == null) {
_log.debug("getMethodInfo: Using workaround for errors array");
Element parent = (Element) methodElement.getParentNode();
Element child = XMLUtilities.getChild(parent, "errors");
if (child != null) {
errorsElement = child;
}
}
List<Error> errors = new ArrayList<Error>();
NodeList errorElements = errorsElement.getElementsByTagName("error");
for (int i = 0; i < errorElements.getLength(); i++) {
Error error = new Error();
Element errorElement = (Element) errorElements.item(i);
error.setCode(errorElement.getAttribute("code"));
error.setMessage(errorElement.getAttribute("message"));
error.setExplaination(XMLUtilities.getValue(errorElement));
errors.add(error);
}
method.setErrors(errors);
return method;
}
/**
* Get a list of all methods.
*
* @return The method names
* @throws FlickrException
*/
public Collection<String> getMethods() throws FlickrException {
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("method", METHOD_GET_METHODS);
Response response = transport.get(transport.getPath(), parameters, apiKey, sharedSecret);
if (response.isError()) {
throw new FlickrException(response.getErrorCode(), response.getErrorMessage());
}
Element methodsElement = response.getPayload();
List<String> methods = new ArrayList<String>();
NodeList methodElements = methodsElement.getElementsByTagName("method");
for (int i = 0; i < methodElements.getLength(); i++) {
Element methodElement = (Element) methodElements.item(i);
methods.add(XMLUtilities.getValue(methodElement));
}
return methods;
}
}