All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.biopax.paxtools.client.BiopaxValidatorClient Maven / Gradle / Ivy

There is a newer version: 6.0.0
Show newest version
package org.biopax.paxtools.client;

/*
 * #%L
 * BioPAX Validator Client
 * %%
 * Copyright (C) 2008 - 2013 University of Toronto (baderlab.org) and Memorial Sloan-Kettering Cancer Center (cbio.mskcc.org)
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.biopax.validator.jaxb.Behavior;
import org.biopax.validator.jaxb.ValidatorResponse;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.nio.charset.Charset;

/**
 * Simple (example) BioPAX Validator client 
 * to upload and check BioPAX OWL files.
 * 
 * @author rodche
 *
 */
public class BiopaxValidatorClient {
	private static final Log log = LogFactory.getLog(BiopaxValidatorClient.class);
	
	/**
	 * Default BioPAX Validator's URL
	 */
	public static final String 
		DEFAULT_VALIDATOR_URL = "http://www.biopax.org/validator/check.html";
	
	/**
	 * The Java Option to set a BioPAX Validator URL
	 * (if set, overrides the default and URL provided by the Constructor arg.)
	 */
	public static final String JVM_PROPERTY_URL = "biopax.validator.url";
	
	public static enum RetFormat {
		HTML,// errors as HTML/Javascript 
		XML, // errors as XML
		OWL; // modified BioPAX only (when 'autofix' or 'normalize' is true)
	}
	
	private String url;

	
    /**
     * Main Constructor
     * 
     * It configures for the validator's URL
     * (defined by DEFAULT_VALIDATOR_URL constant)
     * and result format ().
     * 
     * @param url - validator's file-upload form address
     */
    public BiopaxValidatorClient(String url) {
//		if(url == null || url.isEmpty())
//			this.url = System.getProperty(JVM_PROPERTY_URL, DEFAULT_VALIDATOR_URL);
//		else 
//			this.url = url;
//		
		// 1) use the arg (if not empty/null) or the default URL
    	this.url = (url == null || url.isEmpty())
			? DEFAULT_VALIDATOR_URL : url;
    	
    	// 2) override if the JVM option is set to another value
    	this.url = System.getProperty(JVM_PROPERTY_URL, this.url);
		
    	// 3) get actual location (force through redirects, if any)   	
		try {
			this.url = location(this.url);
//			System.out.println("Location: " + this.url);
		} catch (IOException e) {
			log.warn("Failed to resolve to actual web service " +
				"URL using: " + url + " (if there is a 301/302/307 HTTP redirect, " +
					"then validation requests (using HTTP POST method) will probably fail...)", e);
		}
	}
    
    
    /**
     * Default Constructor
     * 
     * It configures for the default validator URL.
     */
    public BiopaxValidatorClient() {
    	this(null);
	}
       

    /**
     * Checks a BioPAX OWL file(s) or resource 
     * using the online BioPAX Validator 
     * and prints the results to the output stream.
     * 
     * @param autofix true/false (experimental)
     * @param profile validation profile name
     * @param retFormat xml, html, or owl (no errors, just modified owl, if autofix=true)
	 * @param filterBy filter validation issues by the error/warning level
	 * @param maxErrs errors threshold - max no. critical errors to collect before quitting
	 *                (warnings not counted; null/0/negative value means unlimited)
     * @param biopaxUrl check the BioPAX at the URL
     * @param biopaxFiles an array of BioPAX files to validate
     * @param out validation report data output stream
     * @throws IOException when there is an I/O error
     */
    public void validate(boolean autofix, String profile, RetFormat retFormat, Behavior filterBy,
    		Integer maxErrs, String biopaxUrl, File[] biopaxFiles, OutputStream out) throws IOException 
    {
    	MultipartEntityBuilder meb = MultipartEntityBuilder.create();    	
    	meb.setCharset(Charset.forName("UTF-8"));
    	
    	if(autofix)
    		meb.addTextBody("autofix", "true");
//TODO add extra options (normalizer.fixDisplayName, normalizer.inferPropertyOrganism, normalizer.inferPropertyDataSource, normalizer.xmlBase)?
    	if(profile != null && !profile.isEmpty())
    		meb.addTextBody("profile", profile);
    	if(retFormat != null)
    		meb.addTextBody("retDesired", retFormat.toString().toLowerCase());
    	if(filterBy != null)
    		meb.addTextBody("filter", filterBy.toString());
    	if(maxErrs != null && maxErrs > 0)
    		meb.addTextBody("maxErrors", maxErrs.toString());
    	if(biopaxFiles != null && biopaxFiles.length > 0)
    		for (File f : biopaxFiles) //important: use MULTIPART_FORM_DATA content-type
    			meb.addBinaryBody("file", f, ContentType.MULTIPART_FORM_DATA, f.getName());
    	else if(biopaxUrl != null) {
    		meb.addTextBody("url", biopaxUrl);
    	} else {
    		log.error("Nothing to do (no BioPAX data specified)!");
        	return;
    	}
    	
    	//execute the query and get results as string
    	HttpEntity httpEntity = meb.build();
//    	httpEntity.writeTo(System.err);
    	String content = Executor.newInstance()//Executor.newInstance(httpClient)
    			.execute(Request.Post(url).body(httpEntity))
    				.returnContent().asString();  	

    	//save: append to the output stream (file)
		BufferedReader res = new BufferedReader(new StringReader(content));
		String line;
		PrintWriter writer = new PrintWriter(out);
		while((line = res.readLine()) != null) {
			writer.println(line);
		}
		writer.flush();
		res.close();
    }
    
    public void setUrl(String url) {
		this.url = url;
	}
    
    public String getUrl() {
		return url;
	}
    
    /**
     * Converts a biopax-validator XML response to the java object.
     *
     * @param xml input XML data - validation report - to import
     * @return validation report object
     * @throws JAXBException when there is an JAXB unmarshalling error
     */
    public static ValidatorResponse unmarshal(String xml) throws JAXBException {
    	JAXBContext jaxbContext = JAXBContext.newInstance("org.biopax.validator.jaxb");
		Unmarshaller un = jaxbContext.createUnmarshaller();
		Source src = new StreamSource(new StringReader(xml));
		ValidatorResponse resp = un.unmarshal(src, ValidatorResponse.class).getValue();
		return resp;
    }
 
    
    private String location(final String url) throws IOException {
        String location = url; //initially the same
    	// discover actual location, avoid going in circles:
        int i=0;
        for(String loc = url; loc != null && i<5; i++ ) 
        { 	
        	//do POST for location (Location header present if there's a 301/302/307 redirect on the way)
        	loc = Request.Post(loc).execute()
        			.handleResponse(new ResponseHandler() {
						@Override
						public String handleResponse(HttpResponse httpResponse)
								throws ClientProtocolException, IOException {
							Header header = httpResponse.getLastHeader("Location");
//							System.out.println("header=" + header);
							return (header != null) ? header.getValue().trim() : null;
						}
			});
        	 
        	if(loc != null) {
        		location = loc;
        		log.info("BioPAX Validator location: " + loc);
        	}
    	}
        
        return location;
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy