/* Copyright 2006 VPAC
*
* This file is part of qc.
* qc is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
* qc 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with qc; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.vpac.vomrs.model;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.security.cert.CertificateException;
import javax.xml.rpc.ServiceException;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.vpac.common.model.gridproxy.LocalProxy;
import org.vpac.qc.control.common.VOMRS_utils;
import org.vpac.qc.model.clients.ClientNotInitializedException;
import org.vpac.qc.model.clients.GenericClient;
import org.vpac.qc.model.clients.QueryException;
import org.vpac.qc.model.query.Query;
import org.vpac.voms.model.VO;
import fnal.vox.vomrs.services.VOMRS;
import fnal.vox.vomrs.services.VOMRSServiceLocator;
/**
* This class connects to a vomrs server and executes web service queries.
*
* @author Markus Binsteiner
*
*/
public class VomrsClient extends GenericClient {
static final Logger myLogger = Logger
.getLogger(VomrsClient.class.getName());
private URL url = null;
private String[] serviceArguments = null;
private String[] pi = null;
private int startPi = Integer.MAX_VALUE;
/**
* Default constructor
*
* @param url
* the url of the VOMRS server as a string (e.g. new
* VomrsClient(new String[]{
* "https://vomrs.apac.edu.au:8443/vo/APAC/services/VOMRS?wsdl"})
* @param doc
* the root of the xml-config file
* @throws ClientNotInitializedException
*/
public VomrsClient(String url, Document doc)
throws ClientNotInitializedException {
super(new Object[] { url }, doc);
}
/**
* Factory method of the above constructor
*
* @param vo
* the vo
* @param doc
* the root element of the xml config
* @return a VomrsClient for that certain VO
* @throws ClientNotInitializedException
*/
public static VomrsClient getVomrsClient(VO vo, Document doc)
throws ClientNotInitializedException {
return new VomrsClient(vo.getVomrs_url(), doc);
}
/**
* This inits the whole VOMRS webservice and loads all services in the
* methods field.
*
* @throws CertificateException
*
* @throws MalformedURLException
* @throws ServiceException
* @throws RemoteException
* @throws CertificateException
* @throws ServiceException
*/
protected void initializeClient(Object[] args)
throws ClientNotInitializedException {
if (args.length != 1)
throw new ClientNotInitializedException("Wrong set of arguments.");
try {
this.url = new URL((String) args[0]);
} catch (MalformedURLException e) {
throw new ClientNotInitializedException(
"Could not parse URL for VOMRS server.", e);
}
try {
// VOMRS_utils.initVomrsWsWithHostCert();
VOMRS_utils.initVomrsWS();
} catch (CertificateException e1) {
throw new ClientNotInitializedException(
"Could not init VOMRS web services.", e1);
}
VOMRSServiceLocator service = new VOMRSServiceLocator();
try {
stub = service.getVOMRS(url);
} catch (ServiceException e) {
throw new ClientNotInitializedException(e.getMessage(), e);
}
myLogger.debug("Stub successfully initialized. Connected to vomrs web service.");
return;
}
/**
* Returns all the representatives of the VO the VomrsClient is contacting.
* Not important for the GenericClient functionality of this client.
*
* @return all the representatives of this VO
*/
public String[] getRepresentatives() {
String[] representatives = null;
try {
representatives = (String[]) execute("getRepresentatives",
new Object[] {});
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
myLogger.error(e);
}
return representatives;
}
/**
* Returns the information of the user whose grid proxy is used to contact
* the VOMRS server. Not important for the GenericClient functionality of
* this client.
*
* @return information about VO membership
*/
public String[] getMyInfo() {
String[] info = null;
try {
info = (String[]) execute("getMbrInfo", new Object[] {});
} catch (Exception e) {
// does not matter
}
return info;
}
public String[] getAllContexts() {
String[] roles = null;
try {
roles = (String[]) execute("getRoles", new Object[] {});
} catch (Exception e) {
// does not matter
}
return roles;
}
public String[] getMyContexts() {
String[] roles = null;
try {
roles = (String[]) execute("getMbrRoles", new Object[] {});
} catch (Exception e) {
// does not matter
// e.printStackTrace();
myLogger.error(e);
}
if (roles == null || roles.length == 0)
return new String[] { "Visitor" };
return roles;
}
@Override
public String[] getQueryArgumentNames(Query userInputQuery)
throws QueryException {
String[] roles = getAllContexts();
String role = null;
try {
roles = ((VOMRS) stub).getMbrRoles();
role = roles[0];
role = "VOAdmin";
} catch (Exception e) {
role = "Visitor";
}
// String highestRole = null;
// for ( String defaultContext : roles ){
// if ( highestRole == null ) highestRole = defaultContext;
// else {
// }
//
// }
// TODO
return getQueryArgumentNames(userInputQuery, role);
}
/**
* Not implemented. Returns null.
*
* @return
*/
public String[] returnArgumentArray() {
return null;
}
public Object[] formatArgumentValueArray(Object[] argumentValues)
throws ClassCastException {
// pi means personal information in this method.
if (argumentValues.length == 0)
return new Object[] {};
Object[] result = null;
if (startPi == Integer.MAX_VALUE) {
result = new Object[argumentValues.length];
for (int i = 0; i < argumentValues.length; i++) {
result[i] = (String) argumentValues[i];
}
} else {
result = new Object[startPi + 1];
int i;
for (i = 0; i < startPi; i++) {
result[i] = (String) argumentValues[i];
}
// TODO test i
String[] pi_result = new String[pi.length * 2];
for (int j = 0; j < pi.length; j++) {
pi_result[j * 2] = pi[j];
pi_result[j * 2 + 1] = (String) (argumentValues[i + j]);
}
Object temp = (Object) pi_result;
// TODO check this:
startPi = Integer.MAX_VALUE;
result[i] = temp;
}
// ((VOMRS)stub).regi
// result = new Object[]{"VPAC", "/C=AU/O=APACGrid/OU=VPAC/CN=Chris
// Kendrick",
// "/C=AU/O=APACGrid/OU=CA/CN=APACGrid/Email=camanager@vpac.org",
// "full", "markus@vpac.org", ((Object)(new String[]{"First
// name","Markus","Last
// name","Binsteiner","Phone","1234","TestPIParameter1","testpar"}))};
return result;
}
@Override
public String[] getQueryArgumentNames(Query userInputQuery, String role)
throws QueryException {
// if ( parameter.length != 1 ) throw new QueryException("Could not get
// QueryArgument names. Wrong set of parameters for
// "+this.getClass().getName());
// String defaultContext = parameter[0];
// this sets also the servicearguments, startPi and pi field
// TODO check for not-applicable methods
try {
serviceArguments = ((VOMRS) stub).getServiceArguments(
userInputQuery.getName(), role);
if (serviceArguments.length == 0
|| "".equals(serviceArguments[0].toString()))
// TODO check whether I return a non array here???
return new String[0];
if (pi == null)
pi = ((VOMRS) stub).getPI();
} catch (RemoteException e) {
throw new QueryException("Could not get QueryArgument names with "
+ this.getClass().getName() + ": " + e.getMessage());
}
for (String arg : serviceArguments) {
myLogger.debug("QueryArguments: " + arg);
}
for (String arg : pi) {
myLogger.debug("QueryArguments: " + arg);
}
// TODO ok. here it gets dodgy. but I can't think of a better way to
// parse the answer string from vomrs
int index = serviceArguments[0].indexOf(pi[0]);
String[] arg_string_new = null;
if (index == -1) {
// this means, there is no pi in this service request involved
arg_string_new = serviceArguments[0].split(" ");
} else {
serviceArguments = serviceArguments[0].substring(0, index - 1)
.split(" ");
arg_string_new = new String[serviceArguments.length + pi.length];
for (int i = 0; i < serviceArguments.length; i++) {
arg_string_new[i] = serviceArguments[i];
}
startPi = serviceArguments.length;
for (int i = serviceArguments.length; i < arg_string_new.length; i++) {
arg_string_new[i] = pi[i - serviceArguments.length];
}
}
myLogger.debug("New userInputQuery argument names:");
for (String arg : arg_string_new) {
myLogger.debug("QueryArguments: " + arg);
}
return arg_string_new;
}
@Override
public String[] getQueries() {
String[] queries = null;
try {
queries = (String[]) (execute("getServices", new Object[] {}));
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
myLogger.error(e);
}
for (int i = 0; i < queries.length; i++) {
StringBuffer temp = new StringBuffer(queries[i]);
queries[i] = temp.replace(0, 1, temp.substring(0, 1).toLowerCase())
.toString();
}
return queries;
}
@Override
protected void determineDefaultContext() {
String[] myroles = getMyContexts();
if (myroles == null || myroles.length == 0) {
defaultContext = "Visitor";
return;
} else if (myroles.length == 1) {
defaultContext = myroles[0];
return;
} else {
// TODO roles
defaultContext = myroles[myroles.length - 1];
return;
}
}
/**
* Returns the personal information that is required within this VO. Not
* important for the GenericClient functionality of this client.
*
* @return all fields of required personal information within this VO
*/
public String[] getPI() {
String[] pi = null;
try {
pi = (String[]) execute("getPI", new Object[] {});
} catch (Exception e) {
// does not matter
}
return pi;
}
/**
* Returns the personal information of the current user. For description of
* which field is what use the getPI() function. Not important for the
* GenericClient functionality of this client.
*
* @return the personal information of the current user.
*/
public String[] getMyPI() {
String[] pi = null;
try {
pi = (String[]) execute("getMbrPI", new Object[] {});
} catch (Exception e) {
// does not matter
}
return pi;
}
/**
* Returns all subgroups off the current VO. Not important for the
* GenericClient functionality of this client. Just a convenience method
* because it is used more often.
*
* @return all subgroups of this VO.
*/
public String[] getAllGroups() {
String[] allGroups = null;
try {
allGroups = (String[]) execute("getGroups", new Object[] {});
} catch (Exception e) {
// does not matter
}
return allGroups;
}
@Override
public String[] getQueryResultNames(Query query, String role,
Object[] arguments) throws QueryException {
String[] temp = null;
// TODO the null part
try {
temp = (((VOMRS) stub).getServiceReturnValues(query.getName(),
role, ""));
if (pi == null)
pi = ((VOMRS) stub).getPI();
} catch (RemoteException e) {
throw new QueryException("Could not get QueryResultNames with "
+ this.getClass().getName() + ": " + e.getMessage());
}
// TODO ok. here it gets dodgy. but I can't think of a better way to
// parse the answer string from vomrs
int index = temp[0].indexOf(pi[0]);
String[] arg_string_new = null;
if (index == -1) {
// this means, there is no pi in this service request involved
arg_string_new = temp[0].split(" ");
} else {
String temp_pi = temp[0].substring(index);
temp = temp[0].substring(0, index - 1).split(" ");
arg_string_new = new String[temp.length + 1];
int i;
for (i = 0; i < temp.length; i++) {
arg_string_new[i] = temp[i];
}
arg_string_new[i] = temp_pi;
}
myLogger.debug("New userInputQuery returnvalue names:");
for (String arg : arg_string_new) {
myLogger.debug("QueryReturnValue: " + arg);
}
return arg_string_new;
}
// public static void main(String[] args) {
//
// try {
// GenericClient soapClient = new VomrsClient(
// "https://vomrsdev.vpac.org:8443/vo/Markus/services/VOMRS?wsdl" ,
// new File("/home/markus/workspace/voc/queries_test.xml"));
//
// // UserInputQuery userInputQuery = new
// // UserInputQuery("registerMember", soapClient);
// InfoQuery infoQuery = new InfoQuery("registerMember", soapClient,
// "Visitor");
// infoQuery.init();
//
// for (QueryArgument qarg : infoQuery.getArguments()) {
//
// System.out.println("Argument: " + qarg.getName());
// System.out.println("\tType: "
// + qarg.getType().getAttributeValue("name"));
// try {
// try {
// for (Object obj : (Object[]) qarg.getValue()) {
// System.out.println("Object: " + obj + "\tClass: "
// + obj.getClass().toString());
// }
// } catch (ClassCastException e) {
// System.out.println("Single object: " + qarg.getValue()
// + "\tClass: "
// + qarg.getValue().getClass().toString());
// }
// } catch (NullPointerException npe) {
// System.out.println("No value for:" + qarg.getName());
// }
// System.out.println();
//
// }
// infoQuery.submit();
//
// for (Object result : infoQuery.getResult()) {
// System.out.println("Result: " + result.toString());
// }
// Object[] temp = infoQuery.getQueryResultNames();
// for (Object result : temp) {
// System.out.println("Result: " + result.toString());
// }
//
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// }
/**
* Helper function
*
* @param groups
* the groups string returned by the MbrInfo query
* @return all groups the user is member of
*/
public static String[] parseGroups(String groups) {
String[] parsed = groups.substring(1, groups.length() - 1).split(
"\\]\\[");
return parsed;
}
}