import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.Hashtable;
+import java.util.Vector;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
return true;
}
+ protected static Vector<String> services=null;
public static RestClient[] getRestClients()
{
- return new RestClient[] { makeShmmrRestClient() };
+ if (services==null)
+ {
+ services = new Vector<String>();
+ try {
+ for (RestServiceDescription descr: RestServiceDescription.parseDescriptions(jalview.bin.Cache.getDefault("RSBS_SERVICES",makeShmmrRestClient().service.toString())))
+ {
+ services.add(descr.toString());
+ }
+ }
+ catch (Exception ex) {
+ System.err.println("Serious - RSBS descriptions in user preferences are corrupt!");
+ ex.printStackTrace();
+ }
+
+ }
+ RestClient[] lst = new RestClient[services.size()];
+ int i=0;
+ for (String svc:services) {
+ lst[i++] = new RestClient(new RestServiceDescription(svc));
+ }
+ return lst;
+ }
+ public static void main(String args[])
+ {
+ try {
+ RestClient[] clients = getRestClients();
+ System.out.println("Got "+clients.length+" clients.");
+ int i=0;
+ Vector<String> urls=new Vector<String>();
+ for (RestClient cl:clients) {
+ System.out.println(""+(++i)+": "+cl.service.toString());
+ urls.add(cl.service.toString());
+ }
+ setRsbsServices(urls);
+ if (clients.length!=getRestClients().length)
+ {
+ System.err.println("Failed. Differing numbers of clients when stringified and parsed again.");
+ }
+
+ } catch (Throwable x)
+ {
+ System.err.println("Failed. Unexpected exception.");
+ x.printStackTrace();
+ }
}
-
public String getAction()
{
return service.details.Action;
return service;
}
+ public static Vector<String> getRsbsDescriptions()
+ {
+ Vector<String> rsbsDescrs = new Vector<String>();
+ for (RestClient rsbs:getRestClients())
+ {
+ rsbsDescrs.add(rsbs.getRestDescription().toString());
+ }
+ return rsbsDescrs;
+ }
+
+ public static void setRsbsServices(Vector<String> rsbsUrls)
+ {
+ // TODO: consider validating services ?
+ services = new Vector<String>(rsbsUrls);
+ }
+
}
public class RestServiceDescription
{
/**
+ * create a new rest service description ready to be configured
+ */
+ public RestServiceDescription()
+ {
+
+ }
+ /**
* @param details
* @param postUrl
* @param urlSuffix
;
boolean valid = true;
String val = null;
+ int l = warnings.length();
int i;
for (String prop : props)
{
}
if (prop.equals("returns"))
{
- int l = warnings.length();
_configureOutputFormatFrom(val, warnings);
- valid = (l != warnings.length());
}
}
- return valid;
+ // return true if valid is true and warning buffer was not appended to.
+ return valid && (l == warnings.length());
}
private String _genOutputFormatString()
private String getServiceIOProperties()
{
- String[] vls = new String[]
- { isHseparable() ? "hseparable" : "",
- isVseparable() ? "vseparable" : "",
- (new String("gapCharacter='" + gapCharacter + "'")),
- (new String("returns='" + _genOutputFormatString() + "'")) };
-
- return arrayToSeparatorList(vls, ",");
+ ArrayList<String> vls = new ArrayList<String>();
+ if (isHseparable()) { vls.add("hseparable");};
+ if (isVseparable()) { vls.add("vseparable");};
+ vls.add(new String("gapCharacter='" + gapCharacter + "'"));
+ vls.add(new String("returns='" + _genOutputFormatString() + "'"));
+ return arrayToSeparatorList(vls.toArray(new String[0]), ",");
}
public String toString()
{
StringBuffer result = new StringBuffer();
+ result.append("|");
result.append(details.Name);
result.append('|');
result.append(details.Action);
return result.toString();
}
+ /**
+ * processes a service encoded as a string (as generated by RestServiceDescription.toString())
+ * Note - this will only use the first service definition encountered in the string to configure the service.
+ * @param encoding
+ * @param warnings - where warning messages are reported.
+ * @return true if configuration was parsed successfully.
+ */
public boolean configureFromEncodedString(String encoding,
StringBuffer warnings)
{
- boolean invalid = false;
String[] list = separatorListToArray(encoding, "|");
- details.Name = list[0];
- details.Action = list[1];
- details.description = list[2];
- invalid |= !configureFromServiceInputProperties(list[3], warnings);
- if (list.length > 5)
+
+ int nextpos=parseServiceList(list,warnings, 0);
+ if (nextpos>0)
{
- urlSuffix = list[4];
- invalid |= !configureFromInputParamEncodedUrl(list[5], warnings);
+ return true;
+ }
+ return false;
+ }
+ /**
+ * processes the given list from position p, attempting to configure the service from it.
+ * Service lists are formed by concatenating individual stringified services. The first character of a stringified service is '|', enabling this, and the parser will ignore empty fields in a '|' separated list when they fall outside a service definition.
+ * @param list
+ * @param warnings
+ * @param p
+ * @return
+ */
+ protected int parseServiceList(String[] list, StringBuffer warnings, int p)
+ {
+ boolean invalid = false;
+ // look for the first non-empty position - expect it to be service name
+ while (list[p]!=null && list[p].trim().length()==0)
+ {
+ p++;
+ }
+ details.Name = list[p];
+ details.Action = list[p+1];
+ details.description = list[p+2];
+ invalid |= !configureFromServiceInputProperties(list[p+3], warnings);
+ if (list.length-p > 5 && list[p+5]!=null && list[p+5].trim().length()>5)
+ {
+ urlSuffix = list[p+4];
+ invalid |= !configureFromInputParamEncodedUrl(list[p+5], warnings);
+ p+=6;
}
else
{
- if (list.length > 4)
+ if (list.length-p > 4 && list[p+4]!=null && list[p+4].trim().length()>5)
{
urlSuffix = null;
- invalid |= !configureFromInputParamEncodedUrl(list[4], warnings);
+ invalid |= !configureFromInputParamEncodedUrl(list[p+4], warnings);
+ p+=5;
}
}
- return !invalid;
+ return invalid ? -1 : p;
}
-
+
/**
* @return string representation of the input parameters, their type and
* constraints, appended to the service's base submission URL
return resultData;
}
+ /**
+ * parse a concatenated list of rest service descriptions into an array
+ * @param services
+ * @return zero or more services.
+ * @throws exceptions if the services are improperly encoded.
+ */
+ public static List<RestServiceDescription> parseDescriptions(String services) throws Exception
+ {
+ String[] list = separatorListToArray(services, "|");
+ List<RestServiceDescription> svcparsed = new ArrayList<RestServiceDescription>();
+ int p=0,lastp=0;
+ StringBuffer warnings=new StringBuffer();
+ do {
+ RestServiceDescription rsd = new RestServiceDescription();
+ p=rsd.parseServiceList(list, warnings, lastp=p);
+ if (p>lastp && rsd.isValid())
+ {
+ svcparsed.add(rsd);
+ } else {
+ throw new Exception("Failed to parse user defined RSBS services from :"+services+"\nFirst error was encountered at token "+lastp+" starting "+list[lastp]+":\n"+rsd.getInvalidMessage());
+ }
+ } while (p<lastp && p<list.length-1);
+ return svcparsed;
+ }
+
}