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

jlibs.wadl.cli.commands.Method Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
/**
 * Copyright 2015 Santhosh Kumar Tekuri
 *
 * The JLibs authors license this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package jlibs.wadl.cli.commands;

import jlibs.core.io.FileUtil;
import jlibs.core.io.IOUtil;
import jlibs.core.lang.Ansi;
import jlibs.core.lang.JavaProcessBuilder;
import jlibs.core.util.CollectionUtil;
import jlibs.core.util.RandomUtil;
import jlibs.wadl.cli.Util;
import jlibs.wadl.cli.WADLTerminal;
import jlibs.wadl.cli.model.Path;
import jlibs.wadl.cli.ui.Editor;
import jlibs.wadl.model.Representation;
import jlibs.wadl.model.Request;
import jlibs.xml.sax.AnsiHandler;
import jlibs.xml.sax.XMLDocument;
import jlibs.xml.xsd.XSInstance;

import javax.xml.namespace.QName;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.net.HttpURLConnection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

/**
 * @author Santhosh Kumar T
 */
public class Method extends Command{
    private static final Ansi SUCCESS = new Ansi(Ansi.Attribute.BRIGHT, Ansi.Color.GREEN, Ansi.Color.BLACK);
    private static final Ansi FAILURE = new Ansi(Ansi.Attribute.BRIGHT, Ansi.Color.RED, Ansi.Color.BLACK);

    public Method(WADLTerminal terminal){
        super(terminal);
    }

    @Override
    public boolean run(String cmd, List args) throws Exception{
        args.add(0, cmd);
        return execute(args);
    }

    private boolean execute(List args) throws Exception{
        File responseFile = getFile(args, ">");

        HttpURLConnection con = prepare(args);
        if(con==null)
            return false;

        if(con.getResponseCode()==401){ // Unauthorized
            if(authenticate(con))
                return execute(args);
            else
                return false;
        }
        Ansi result = con.getResponseCode()/100==2 ? SUCCESS : FAILURE;
        result.outln(con.getResponseCode()+" "+con.getResponseMessage());
        System.out.println();

        boolean success = true;
        InputStream in = con.getErrorStream();
        if(in==null)
            in = con.getInputStream();
        else
            success = false;

        PushbackInputStream pin = new PushbackInputStream(in);
        int data = pin.read();
        if(data==-1){
            if(responseFile!=null)
                responseFile.delete();
            return success;
        }
        pin.unread(data);
        if(success && responseFile!=null){
            IOUtil.pump(pin, new FileOutputStream(responseFile), true, true);
            return true;
        }

        String contentType = con.getContentType();
        if(Util.isXML(contentType)){
            PrintStream sysErr = System.err;
            System.setErr(new PrintStream(new ByteArrayOutputStream()));
            try {
                TransformerFactory factory = TransformerFactory.newInstance();
                Transformer transformer = factory.newTransformer();
                transformer.transform(new StreamSource(pin), new SAXResult(new AnsiHandler()));
                transformer.reset();
                return success;
            } catch (Exception ex) {
                sysErr.println("response is not valid xml: "+ex.getMessage());
                return false;
            } finally {
                System.setErr(sysErr);
            }
        }
        if(Util.isPlain(contentType) || Util.isJSON(contentType) || Util.isHTML(contentType)){
            IOUtil.pump(pin, System.out, true, false);
            System.out.println();
        }else{
            File temp = File.createTempFile("attachment", "."+Util.getExtension(contentType), FileUtil.USER_DIR);
            IOUtil.pump(pin, new FileOutputStream(temp), true, true);
            System.out.println("response saved to "+temp.getAbsolutePath());
        }
        return success;
    }

    private File getFile(Listargs, String argPrefix){
        File file = null;
        Iterator iter = args.iterator();
        while(iter.hasNext()){
            String arg = iter.next();
            if(arg.startsWith(argPrefix)){
                iter.remove();
                file = Util.toFile(arg.substring(1));
            }
        }
        return file;
    }
    
    private HttpURLConnection prepare(List args) throws Exception{
        String methodName = args.remove(0);

        File payload = getFile(args, "<");
        Path path = terminal.getCurrentPath();
        if(!args.isEmpty()){
            String pathString = args.get(0);
            if(pathString.indexOf('=')==-1 && pathString.indexOf(':')==-1
                    && !pathString.startsWith(">") && !pathString.startsWith("<")){
                path = path.get(args.remove(0));
            }
        }
        if(path==null || path.resource==null){
            System.err.println("resource not found");
            return null;
        }

        jlibs.wadl.model.Method method = path.findMethod(methodName);
        if(method==null){
            System.err.println("unsupported method: "+methodName);
            return null;
        }

        Request request = method.getRequest();

        if(payload==null && request!=null){
            if(!request.getRepresentation().isEmpty()){
                Representation rep = request.getRepresentation().get(RandomUtil.random(0, request.getRepresentation().size() - 1));
                if(rep.getElement()!=null){
                    payload = FILE_PAYLOAD;
                    generatePayload(path, rep.getElement());
                }
            }
            if(payload!=null){
                JavaProcessBuilder processBuilder = new JavaProcessBuilder();
                StringTokenizer stok = new StringTokenizer(System.getProperty("java.class.path"), FileUtil.PATH_SEPARATOR);
                while(stok.hasMoreTokens())
                    processBuilder.classpath(stok.nextToken());
                processBuilder.mainClass(Editor.class.getName());
                processBuilder.arg(payload.getAbsolutePath());
                processBuilder.arg("text/xml");
                processBuilder.launch(DUMMY_OUTPUT, DUMMY_OUTPUT).waitFor();
                if(!payload.exists())
                    return null;
            }
        }

        return path.execute(method, args, payload);
    }

    private static final File FILE_PAYLOAD = new File("temp.xml");
    private void generatePayload(Path path, QName element) throws Exception{
        if(path.variable()!=null){
            for(Object item: path.resource.getMethodOrResource()){
                if(item instanceof jlibs.wadl.model.Method){
                    jlibs.wadl.model.Method method = (jlibs.wadl.model.Method)item;
                    if(method.getName().equalsIgnoreCase("GET")){
                        try{
                            HttpURLConnection con = path.execute(method, Collections.emptyList(), null);
                            if(con.getResponseCode()==200){
                                IOUtil.pump(con.getInputStream(), new FileOutputStream(FILE_PAYLOAD), true, true);
                                return;
                            }
                        }catch(Exception ex){
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }

        XSInstance xsInstance = new XSInstance();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("xsd-instance.properties");
        if(is!=null)
            xsInstance.loadOptions(CollectionUtil.readProperties(is, null));
        XMLDocument xml = new XMLDocument(new StreamResult(FILE_PAYLOAD), true, 4, null);
        xsInstance.generate(path.getSchema(), element, xml);
    }

    public boolean authenticate(HttpURLConnection con) throws IOException{
        String value = con.getHeaderField("WWW-Authenticate");
        if(value==null)
            return false;
        int space = value.indexOf(' ');
        if(space==-1)
            return false;
        if(!Authenticate.authenticate(terminal, value.substring(0, space), Collections.emptyList()))
            return false;
        return true;
    }

    private static final OutputStream DUMMY_OUTPUT = new OutputStream(){
        @Override
        public void write(int b) throws IOException{}
        @Override
        public void write(byte[] b) throws IOException{}
        @Override
        public void write(byte[] b, int off, int len) throws IOException{}
    };
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy