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

org.sikuli.script.ImagePath Maven / Gradle / Ivy

There is a newer version: 2.0.5
Show newest version
/*
 * Copyright (c) 2010-2019, sikuli.org, sikulix.com - MIT license
 */
package org.sikuli.script;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.sikuli.basics.Debug;
import org.sikuli.basics.FileManager;
import org.sikuli.basics.Settings;
import org.sikuli.script.support.RunTime;

/**
 * maintain the path list of locations, where images will be searched.
 * 
the first entry always is the bundlepath used on the scripting level
* Python import automatically adds a sikuli bundle here
* supported locations:
* - absolute filesystem paths
* - inside jars relative to root level given by a class found on classpath
* - a location in the web given as string starting with http[s]://
* - any location as a valid URL, from where image files can be loaded
*/ public class ImagePath { private static final String me = "ImagePath: "; private static final int lvl = 3; private static void log(int level, String message, Object... args) { Debug.logx(level, me + message, args); } // private static final List imagePaths = Collections.synchronizedList(new ArrayList()); static { imagePaths.add(null); } /** * get the list of path entries (as PathEntry) * * @return pathentries */ public static List getPaths() { return imagePaths; } private static int getCount() { int count = imagePaths.size(); for (PathEntry path : imagePaths) { if (path == null) { count--; } } return count; } /** * the path list as string array * * @return an array of the file path's currently in the path list */ public static String[] get() { int i = 0; for (PathEntry p : imagePaths) { if (p == null) { continue; } i++; } String[] paths = new String[i]; i = 0; for (PathEntry p : imagePaths) { if (p == null) { continue; } paths[i++] = p.getPath(); if (p.isFile()) { paths[i - 1] = new File(p.getPath()).getAbsolutePath(); } } return paths; } /** * print the list of path entries * * @param lvl debug level to use */ public static void dump(int lvl) { log(lvl, "ImagePath has %d entries (valid %d)", imagePaths.size(), getCount()); String bundle = "(taken as bundle path)"; for (PathEntry p : imagePaths) { if (p == null) { log(lvl, "Path: NULL %s", bundle); } else { log(lvl, "Path: given: %s\nis: %s", p.path, p.getPath()); } bundle = ""; } } /** * empty path list and keep bundlePath (entry 0)
* Image cache is cleared completely * convenience for the scripting level */ public static void reset() { log(lvl, "reset"); if (imagePaths.isEmpty()) { return; } for (PathEntry pathEntry : imagePaths) { if (pathEntry == null) { continue; } Image.purge(pathEntry); } PathEntry bundlePath = getBundle(); imagePaths.clear(); imagePaths.add(bundlePath); } //
// /** * represents an imagepath entry */ public static class PathEntry { public URL pathURL = null; public String path = null; /** * create a new image path entry * * @param givenName the given path relative or absolute * @param eqivalentURL the evaluated URL */ public PathEntry(String givenName, URL eqivalentURL) { path = FileManager.normalize(givenName); if (eqivalentURL != null) { pathURL = eqivalentURL; } else { pathURL = makePathURL(path, null).pathURL; } log(lvl + 1, "ImagePathEntry: %s (%s)", path, pathURL); } public PathEntry(File folder) { try { path = folder.getPath(); pathURL = new URL("file", null, path); log(lvl + 1, "ImagePathEntry: %s (%s)", path, pathURL); } catch (IOException e) { log(-1, "ImagePathEntry: %s", folder); } } public boolean isValid() { return path != null && pathURL != null; } public String getPath() { if (pathURL == null) { return "-- empty --"; } if (isFile()) { return pathURL.getPath(); } return null; } public boolean isFile() { if (pathURL == null) { return false; } return "file".equals(pathURL.getProtocol()); } public boolean isJar() { if (pathURL == null) { return false; } return "jar".equals(pathURL.getProtocol()); } public boolean isHTTP() { if (pathURL == null) { return false; } return pathURL.getProtocol().startsWith("http"); } public File getFile() { if (isFile()) { return new File(getPath()); } return null; } public boolean existsFile() { if (pathURL == null) { return false; } return new File(getPath()).exists(); } @Override public boolean equals(Object other) { if (pathURL == null) { return false; } if (!(other instanceof PathEntry)) { if (other instanceof URL) { if (pathURL.equals(other)) { return true; } } else if (other instanceof String) { if (isFile()) { try { return new File(pathURL.getFile()).equals(new File((String) other).getCanonicalFile()); } catch (IOException e) { return false; } } return false; } else if (other instanceof File) { if (isFile()) { try { return new File(pathURL.getFile()).equals(((File) other).getCanonicalFile()); } catch (IOException e) { return false; } } return false; } return false; } if (pathURL.equals(((PathEntry) other).pathURL)) { return true; } return false; } @Override public String toString() { return getPath(); } } private static PathEntry makePathURL(String fpMainPath, String fpAltPath) { if (fpMainPath == null || fpMainPath.isEmpty()) { return null; } URL pathURL = null; File fPath = new File(FileManager.normalizeAbsolute(fpMainPath)); if (fPath.exists()) { pathURL = FileManager.makeURL(fPath.getAbsolutePath()); } else { if (fpMainPath.contains("\\")) { log(-1, "add: folder does not exist (%s)", fPath); return null; } Class cls = null; String klassName; String fpSubPath = ""; int n = fpMainPath.indexOf("/"); if (n > 0) { klassName = fpMainPath.substring(0, n); if (n < fpMainPath.length() - 2) { fpSubPath = fpMainPath.substring(n + 1); } } else { klassName = fpMainPath; } try { cls = Class.forName(klassName); } catch (ClassNotFoundException ex) { log(-1, "add: class not found (%s) or folder does not exist (%s)", klassName, fPath); } if (cls != null) { CodeSource codeSrc = cls.getProtectionDomain().getCodeSource(); if (codeSrc != null && codeSrc.getLocation() != null) { URL jarURL = codeSrc.getLocation(); if (jarURL.getPath().endsWith(".jar")) { pathURL = FileManager.makeURL(jarURL.toString() + "!/" + fpSubPath, "jar"); } else { if (fpAltPath == null || fpAltPath.isEmpty()) { fpAltPath = jarURL.getPath(); } if (new File(FileManager.normalizeAbsolute(fpAltPath), fpSubPath).exists()) { File fAltPath = new File(FileManager.normalizeAbsolute(fpAltPath), fpSubPath); pathURL = FileManager.makeURL(fAltPath.getPath()); } } } } } if (pathURL != null) { return new PathEntry(fpMainPath, pathURL); } return null; } // // /** * create a new PathEntry from the given absolute path name and add it to the * end of the current image path
* for usage with jars see; {@link #add(String, String)} * * @param mainPath relative or absolute path * @return true if successful otherwise false */ public static boolean add(String mainPath) { return add(mainPath, null); } /** * create a new PathEntry from the given net resource folder accessible via HTTP at * end of the current image path
* BE AWARE:
* Files stored in the given remote folder must allow HTTP HEAD-requests (checked)
* redirections are not followed (suppressed) * * @param pathHTTP folder address like siteaddress or siteaddress/folder/subfolder (e.g. download.sikuli.de/images) * @return true if successful otherwise false */ public static boolean addHTTP(String pathHTTP) { try { String proto = "http://"; String protos = "https://"; if (pathHTTP.startsWith(proto) || pathHTTP.startsWith(protos)) { proto = ""; } pathHTTP = FileManager.slashify(pathHTTP, false); URL aURL = new URL(proto + pathHTTP); if (0 != FileManager.isUrlUseabel(new URL(aURL.toString() + "/THIS_FILE_SHOULD_RETURN_404"))) { return false; } PathEntry path = new PathEntry(pathHTTP, aURL); if (hasPath(path) < 0) { log(lvl, "add: %s", path); imagePaths.add(path); } else { log(lvl, "duplicate not added: %s", path); } } catch (Exception ex) { log(-1, "addHTTP: not possible: %s\n%s", pathHTTP, ex); return false; } return true; } public static boolean removeHTTP(String pathHTTP) { try { String proto = "http://"; String protos = "https://"; if (pathHTTP.startsWith(proto) || pathHTTP.startsWith(protos)) { proto = ""; } pathHTTP = FileManager.slashify(pathHTTP, false); return remove(new URL(proto + pathHTTP)); } catch (Exception ex) { log(-1, "removeHTTP: not possible: %s\n%s", pathHTTP, ex); return false; } } /** * create a new PathEntry from the given absolute path name and add it to the * end of the current image path
* for images stored in jars:
* Set the primary image path to the top folder level of a jar based on the * given class name (must be found on class path). When not running from a jar * (e.g. running in some IDE) the path will be the path to the compiled * classes (for Maven based projects this is target/classes that contains all * stuff copied from src/run/resources automatically)
* For situations, where the images cannot be found automatically in the non-jar situation, you * might give an alternative path either absolute or relative to the working folder. * * @param mainPath absolute path name or a valid classname optionally followed by /subfolder... * @param altPath alternative image folder, when not running from jar * @return true if successful otherwise false */ public static boolean add(String mainPath, String altPath) { PathEntry pathEntry = null; File fPath = new File(mainPath); if (!fPath.isAbsolute() && mainPath.contains(":")) { if (fPath.getAbsolutePath().charAt(2) != ":".charAt(0)) { return addHTTP(mainPath); } } pathEntry = makePathURL(mainPath, altPath); if (pathEntry != null) { if (hasPath(pathEntry) < 0) { log(lvl, "add: %s", pathEntry); imagePaths.add(pathEntry); } else { log(lvl, "duplicate not added: %s", pathEntry); } return true; } else { log(-1, "add: not valid: %s %s", mainPath, (altPath == null ? "" : " / " + altPath)); } return false; } public static boolean addJar(String fpJar, String fpImage) { URL pathURL = null; if (".".equals(fpJar)) { fpJar = RunTime.get().fSxBaseJar.getAbsolutePath(); if (!fpJar.endsWith(".jar")) { return false; } } if (new File(fpJar).exists()) { if (fpImage == null) { fpImage = ""; } log(3, "addJar: %s", fpJar); pathURL = FileManager.makeURL(fpJar + "!/" + fpImage, "jar"); add(pathURL); } return true; } private static int hasPath(PathEntry path) { PathEntry bundle = getBundle(); if (imagePaths.size() == 1 && bundle == null) { return -1; } if (bundle != null && bundle.equals(path)) { return 0; } for (PathEntry pathEntry : imagePaths.subList(1, imagePaths.size())) { if (pathEntry != null && pathEntry.equals(path)) { return 1; } } return -1; } /** * add entry to end of list (the given URL is not checked) * * @param pURL a valid URL (not checked) */ public static void add(URL pURL) { imagePaths.add(new PathEntry("__PATH_URL__", pURL)); } /** * remove entry with given path (same as given with add) * * @param path relative or absolute path * @return true on success, false otherwise */ public static boolean remove(String path) { File fPath = new File(path); if (!fPath.isAbsolute() && (path.contains("http://") || path.contains("https://"))) { return removeHTTP(path); } return remove(makePathURL(FileManager.normalize(path), null).pathURL); } /** * remove entry with given path (same as given with add) * * @param directory * @return true on success, false otherwise */ public static boolean remove(File directory) { return remove(makePathURL(directory.getAbsolutePath(), null).pathURL); } /** * remove entry with given URL
* bundlepath (entry 0) cannot be removed * loaded images are removed from cache * * @param pURL a valid URL (not checked) * @return true on success, false ozherwise */ private static boolean remove(URL pURL) { if (bundleEquals(pURL)) { Image.purge(); return true; } Iterator it = imagePaths.subList(1, imagePaths.size()).iterator(); PathEntry pathEntry; while (it.hasNext()) { pathEntry = it.next(); if (!pathEntry.equals(pURL)) { continue; } it.remove(); Image.purge(pathEntry); } return true; } //
// public static boolean hasBundlePath() { return getBundle() != null; } private static boolean bundleEquals(Object path) { if (hasBundlePath()) { return getBundle().equals(path); } return false; } /** * empty path list and add given path as first entry * Image cache is cleared completely * * @param path absolute path * @return true on success, false otherwise */ public static boolean reset(String path) { reset(); if (bundleEquals(path)) { return true; } return setBundlePath(path); } private static boolean setBundlePath() { return setBundlePath(null); } /** * the given path replaces bundlepath (entry 0) * * @param newBundlePath an absolute file path * @return true on success, false otherwise */ public static boolean setBundlePath(String newBundlePath) { if (newBundlePath == null) { newBundlePath = Settings.BundlePath; if (newBundlePath == null) { return false; } } File newBundleFile = new File(newBundlePath); if (!newBundleFile.isAbsolute()) { if (hasBundlePath()) { return false; } newBundleFile = new File(getBundlePath(), newBundlePath); } return null != setBundleFolder(newBundleFile); } public static File setBundleFolder(File folder) { try { folder = folder.getCanonicalFile(); } catch (IOException e) { log(-1, "canonical file problem: %s", folder); return null; } if (null == folder || bundleEquals(folder)) { return folder; } if (folder.exists()) { PathEntry oldBundle = getBundle(); Image.purge(oldBundle); PathEntry pathEntry = new PathEntry(folder); if (pathEntry.isValid()) { setBundle(pathEntry); log(lvl, "new BundlePath: %s", pathEntry); return pathEntry.getFile(); } } return null; } static PathEntry getBundle() { return imagePaths.get(0); } private static void setBundle(PathEntry pathEntry) { imagePaths.set(0, pathEntry); } /** * no trailing path separator * * @return the current bundle path */ public static String getBundlePath() { if (!hasBundlePath()) { if (!setBundlePath()) { return null; } } return getBundle().getPath(); } // // /** * try to find the given relative image file name on the image path
* starting from entry 0, the first found existence is taken
* absolute file names are checked for existence * * @param imageFileName relative or absolute filename * @return a valid URL or null if not found/exists */ public static URL find(String imageFileName) { URL fURL = null; String proto = ""; File imageFile = new File(imageFileName); if (imageFile.isAbsolute()) { if (imageFile.exists()) { try { fURL = new URL("file", null, new File(imageFileName).getPath()); } catch (MalformedURLException e) { } } else { log(-1, "find: File does not exist: %s", imageFileName); } return fURL; } else { for (PathEntry path : getPaths()) { if (path == null) { continue; } proto = path.pathURL.getProtocol(); if ("file".equals(proto)) { if (new File(path.pathURL.getPath(), imageFileName).exists()) { try { fURL = new URL("file", null, new File(path.pathURL.getPath(), imageFileName).getPath()); break; } catch (MalformedURLException e) { } } } else if ("jar".equals(proto) || proto.startsWith("http")) { fURL = FileManager.getURLForContentFromURL(path.pathURL, imageFileName); if (fURL != null) { break; } } } if (fURL == null) { log(-1, "find: not there: %s", imageFileName); dump(lvl); } return fURL; } } /** * given absolute or relative (searched on image path) file name
* is tried to open as a BufferedReader
* BE AWARE: use br.close() when finished * * @param fname relative or absolute filename * @return the BufferedReader to be used or null if not possible */ public static BufferedReader open(String fname) { log(lvl, "open: " + fname); URL furl = find(fname); if (furl != null) { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(furl.openStream())); } catch (IOException ex) { log(-1, "open: %s", ex.getMessage()); return null; } try { br.mark(10); if (br.read() < 0) { br.close(); return null; } br.reset(); return br; } catch (IOException ex) { log(-1, "open: %s", ex.getMessage()); try { br.close(); } catch (IOException ex1) { log(-1, "open: %s", ex1.getMessage()); return null; } return null; } } return null; } public static boolean isImageBundled(URL fURL) { if ("file".equals(fURL.getProtocol())) { return bundleEquals(new File(fURL.getPath()).getParent()); } return false; } //
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy