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

org.dynamide.restreplay.ResourceManager Maven / Gradle / Ivy

Go to download

RestReplay is a dynamide.org utility to send REST requests to the services layer (including JSON, XML, and multipart XML requests), read responses, validate responses, and compare the resulting payloads with templates.

There is a newer version: 1.0.27
Show newest version
package org.dynamide.restreplay;

import org.apache.commons.io.FileUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.dynamide.util.FileTools;
import org.dynamide.util.Tools;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class ResourceManager {

    public static class Resource{
        public enum SOURCE {FILE,CLASSPATH,STREAM,URL,ZIP,NOTFOUND}
        public Document document;
        public String contents = "";
        public String name = "";
        public String relPath = "";
        public String base = "";
        public String foundPath = "";
        public SOURCE provider;
        public String context = "";
        public boolean cached = false;
        public boolean relative = true;
        public String getDocumentSnippet(){
            String docstring = "";
            if (document!=null){
                String name = document.getName();
                if (name != null){
                    docstring = name;
                } else {
                    Node root = document.getRootElement();
                    if (root!=null){
                        docstring = "<"+root.getName()+"...";
                    } else {
                        docstring = document.getClass().getSimpleName();
                    }
                }
            }
            return docstring;
        }
        public String toString(){
            return "Resource: {context:"+context
                    +", doc:"+getDocumentSnippet()
                    +", name:"+name
                    +", path:"+relPath
                    +", base:"+base
                    +", fullpath:"+foundPath
                    +", provider:"+provider.toString()
                    +"}";
        }
    }

    private static final class CachedDoc {
        public CachedDoc(Document document){
            this.document = document;
        }
        public Document document;
    }

    private final List resourceHistory = new ArrayList();

    private final Map cache = new LinkedHashMap();

    private final Map docCache = new LinkedHashMap();

    public static ResourceManager createRootResourceManager(){
        return new ResourceManager();
    }

    private ConfigFile provider;
    public void setTestContextProvider(ConfigFile provider){
        this.provider = provider;
    }
    protected String getContextProviderContext(){
        if (this.provider != null){
            return provider.getCurrentTestIDLabel();
        }
        return "";
    }

    public static String getRestReplayVersion() {
        Properties properties = readPropertiesFromClasspath();
        Object propObj = properties.get("application.version");
        if (propObj != null) {
            return propObj.toString();
        }
        return "";
    }

    //I tested, and the correct form for this is *without* the slash before a relative resourcename on the classpath.
    //InputStream res2 = RestReplay.class.getClassLoader().getResourceAsStream("/restreplay/"+masterFilename);
    //System.out.println("$$$$$$$$ getResource "+"/restreplay/"+masterFilename+":2-->"+res2+"<--");

    public org.dom4j.Document getDocument(String context, String testdir, String relResourcePath) throws DocumentException {
        boolean markForCache = false;
        CachedDoc cachedDoc = docCache.get(relResourcePath);

        //implement a cache that caches on the *second* access.
        if (cachedDoc != null && cachedDoc.document != null  ){
            if ( cachedDoc.document == null){
                markForCache = true;
            } else {
                return cachedDoc.document;
            }
        }

        org.dom4j.Document document;
        Resource resource = new Resource();
        resource.context = context;
        resource.base = testdir;
        resource.relPath = relResourcePath;
        resourceHistory.add(resource);
        String fullPath = Tools.glue(testdir, "/", relResourcePath);
        if (new File(fullPath).exists()) {
            document = new SAXReader().read(fullPath);
            resource.provider = Resource.SOURCE.FILE;
            resource.foundPath = fullPath;
        } else {
            InputStream stream = RestReplay.class.getClassLoader().getResourceAsStream("restreplay/" + relResourcePath);  // restreplay/ is on the classpath (in the jar).
            if (stream != null) {
                document = new SAXReader().read(stream);
                resource.provider = Resource.SOURCE.CLASSPATH;
                resource.relPath = relResourcePath;
                resource.foundPath = relResourcePath;
            } else {
                resource.provider = Resource.SOURCE.NOTFOUND;
                //System.out.println("ERROR: File does not exist: " + fullPath + ", calculated for: " + relResourcePath);
                return null;
            }
        }
        resource.document = document;

        if (markForCache){
            //System.out.println("====adding to docCache===>>>"+relResourcePath);
            docCache.put(relResourcePath, new CachedDoc(document));  //second time actually cache it.
            resource.cached = true;
        } else {
            docCache.put(relResourcePath, new CachedDoc(null));  //first time is empty string
        }

        return document;
    }

    protected static final Resource CACHE_NEXT_TIME = new Resource();

    /** Internally, this implements a write-on-second-access cache, because we end up reading many small
     *  files once, and a few files many times.
     * @param context
     * @param relResourcePath
     * @param fullPath
     * @return
     * @throws IOException
     */
    public Resource readResource(String context, String relResourcePath, String fullPath) throws IOException {
        //System.out.println("===> resource: "+relResourcePath
        //              +"\r\n     fullPath: "+fullPath);
        boolean markForCache = false;
        Resource cachedResource = cache.get(relResourcePath);
        //implement a cache that caches on the *second* access.
        if (cachedResource != null){
            if (cachedResource != CACHE_NEXT_TIME){
                return cachedResource;
            } else {
                markForCache = true;
            }
        }

        org.dom4j.Document document;
        Resource resource = new Resource();
        resource.context = context+" ["+this.getContextProviderContext()+"]";
        //resource.base = testdir;
        resource.relPath = relResourcePath;
        resourceHistory.add(resource);


        if (Tools.notBlank(relResourcePath)) {
            InputStream stream = RestReplay.class.getClassLoader().getResourceAsStream("restreplay/" + relResourcePath);  // restreplay/ is on the classpath (in the jar).
            if (stream != null) {
                //System.out.println("======> found stream for relResourcePath: -->" + relResourcePath + "<--, not fullPath:-->" + fullPath + "<--");
                String res = FileTools.convertStreamToString(stream);
                //System.out.println("======> stream starts with:" + res.substring(0, Math.min(res.length(), 100)));
                resource.provider = Resource.SOURCE.CLASSPATH;
                resource.relPath = relResourcePath;
                resource.foundPath = relResourcePath;
                resource.contents = res;
                if (markForCache){
                    resource.cached = true;
                    //System.out.println("====adding to cache===>>>"+relResourcePath);
                    cache.put(relResourcePath, resource);  //second time actually cache it.
                } else {
                    cache.put(relResourcePath, CACHE_NEXT_TIME);  //first time is empty string
                }
                return resource;
            }
        }
        //System.out.println("======> using File for fullPath: "+fullPath);
        File fullPathFile = new File(fullPath);
        File relResourcePathFile = new File(relResourcePath);
        File theFile = null;
        if (relResourcePathFile.exists()) {
            theFile = relResourcePathFile;
            resource.foundPath = relResourcePath;
            resource.relative = false;  //We found it using the relative path, which turned out to be a full path.
        } else if (fullPathFile.exists()) {
            theFile = fullPathFile;
            resource.foundPath = fullPath;
            resource.relative = true;  //relPath not found, so fullPath has the test dir already glued on ==> relative.
        }

        if (theFile!=null && theFile.exists()){
            byte[] b = FileUtils.readFileToByteArray(theFile);
            String res = new String(b);
            resource.provider = Resource.SOURCE.FILE;
            resource.contents = res;
            if (markForCache) {
                cache.put(relResourcePath, resource);  //second time actually cache it.
                resource.cached = true;
            } else {
                cache.put(relResourcePath, CACHE_NEXT_TIME);  //first time is empty string
            }
            return resource;
        } else {
            resource.provider = Resource.SOURCE.NOTFOUND;
            return resource;
        }
    }

    public static Properties readPropertiesFromClasspath() {
        Properties prop = new Properties();
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream stream = loader.getResourceAsStream("application.properties");
        if (stream!=null){
            try {
                prop.load(stream);
            } catch (IOException e){
                System.out.println("ERROR reading properties for application.properties :"+e);
            }
        }
        return prop;
    }

    private static final String formatSummaryLine(String css, String name, String value){
        if (Tools.isBlank(value)){
            return "";
        }
        return "
  "+name+" "+value; } private static final String formatSummaryLinePlain(String name, String value){ if (Tools.isBlank(value)){ return ""; } return "\r\n "+name+" "+value; } public String formatSummary(){ StringBuffer b = new StringBuffer(); b.append(""); for (Resource resource: resourceHistory){ boolean notFound = resource.provider.equals(Resource.SOURCE.NOTFOUND); String css; List classes = new ArrayList(); if (notFound){ classes.add("resource-not-found"); } if (resource.cached){ classes.add("resource-cached"); } if (!resource.relative){ classes.add("resource-fullpath"); } b.append(""); } b.append("
") .append("" + resource.relPath + "") .append(formatSummaryLine("SMALL res-mananger-caption", "base:", resource.base)) .append(formatSummaryLine("SMALL res-mananger-caption", "foundPath:",resource.foundPath)) .append(formatSummaryLine("SMALL res-mananger-caption", "source: ", (notFound ? ""+resource.provider.toString()+"" : resource.provider.toString() ))) .append(formatSummaryLine("SMALL res-mananger-caption", "context:", resource.context)) .append(formatSummaryLine("SMALL res-mananger-caption", "doc:", resource.getDocumentSnippet())) .append(formatSummaryLine("SMALL res-mananger-caption", "cached:", resource.cached?"true":"")) .append(formatSummaryLine("SMALL res-mananger-caption", "fullpath:", (!resource.relative)?"true":"")) .append("
"); return b.toString(); } public String formatSummaryPlain(){ StringBuffer b = new StringBuffer(); b.append("ResourceManager History"); final String BR = "\r\n"; for (Resource resource: resourceHistory){ b.append(BR) .append(resource.relPath) .append(formatSummaryLinePlain("base:", resource.base)) .append(formatSummaryLinePlain("foundPath:",resource.foundPath)) .append(formatSummaryLinePlain("source:", resource.provider.toString())) .append(formatSummaryLinePlain("context:", resource.context)) .append(formatSummaryLinePlain("doc:", resource.getDocumentSnippet())) .append(formatSummaryLinePlain("cached:", resource.cached ? "true" : "")) .append(formatSummaryLinePlain("fullpath:", (!resource.relative) ? "true" : "")); } return b.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy