Revision history [back]

click to hide/show revision 1
initial version

answered 2015-05-25 11:53:14 +0800

gargamel25 gravatar image gargamel25

Hi cor3000,

Thanks for the quick response.

Although I personally would have chosen one of your solutions my requirements were to make the developers job very easy, so to add a metadata in a zul file like:

<?viewDescriptor domainContext="user"?>

was the most simple thing and somehow equivalent to a java annotation. Your solution implies some extra work to do : to add a linked java class to the zul or to add some configuration in lang-addon to define the macro.

So it has been decided to follow the solution with adding some processing instruction to zuls .

The discovery of the zuls is something like this:

public class Factory {

private static final Factory instance = new Factory();
private List<WebViewDescriptor> zuls = new ArrayList<>();
private boolean init = false;
Pattern regex = Pattern.compile("<\\?viewDescriptor.+domainContext=\"(.*)\".*\\?>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
boolean IS_WINDOWS = System.getProperty("os.name").contains("indow");

public static Factory getInstance() {
    return instance;
}

public synchronized List<WebViewDescriptor> getAvailableZuls() {
    if (!init) {
        try {
            discover();
        } catch (Exception e) {
            Log.error(e, getClass(), "Error initializing web view descriptors");
        }
    }
    return zuls;

}

@SuppressWarnings("unchecked")
public synchronized void discover() throws Exception {

    // webapp including WEB-INF/classes
    String webapp = Sessions.getCurrent().getWebApp().getServletContext().getRealPath("/").replaceAll("\\\\", "\\\\\\\\");
    Collection<File> listFiles = FileUtils.listFiles(new File(webapp), new String[] { "zul" }, true);
    for (File f : listFiles) {

        List<String> lines = Files.readAllLines(Paths.get(f.getAbsolutePath()), StandardCharsets.UTF_8);
        for (String line : lines) {

            Matcher regexMatcher = regex.matcher(line);
            if (regexMatcher.find()) {
                String src = f.getAbsolutePath().replaceFirst(webapp, "").replaceAll("\\\\", "/");
                if (src.startsWith("WEB-INF/classes/web/")) {
                    src = "/~./" + src.replaceFirst("WEB-INF/classes/web/", "");
                } else if (src.startsWith("WEB-INF")) {
                    src = "/" + src;
                }
                String name = src;
                if(src.lastIndexOf("/") != -1) {
                    name = src.substring(src.lastIndexOf("/")+1);
                }


                String domainContextStr = regexMatcher.group(1);
                List<String> domainContextList = new ArrayList<>();
                if(domainContextStr.lastIndexOf(",") != -1) {
                    domainContextList.add(domainContextStr);
                } else {
                    domainContextList.addAll(Arrays.asList(domainContextStr.split(",")));
                }
                zuls.add(new WebViewDescriptor(src, name, domainContextList));
                break;
            }
        }
    }

    // jars WEB-INF/lib/
    //if we also need other folders we need a recursive method while(classLoader.getParent() != null)

    ClassLoader classLoader = getClass().getClassLoader();
    URL[] urls = ((URLClassLoader) classLoader).getURLs();
    for (int i = 0 ; i < urls.length; i++) {

        String filePath = urls[i].getPath();
        filePath = IS_WINDOWS ? filePath.substring(1) : filePath;
        filePath = URLDecoder.decode(filePath, "UTF-8");
        if(filePath.endsWith(".jar")) {
            try (FileSystem fs = FileSystems.newFileSystem(Paths.get(filePath), null)) {
                Iterable<Path> dirs = fs.getRootDirectories();

                for (Path root : dirs) {
                    Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
                        private final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.{zul}");

                        @Override
                        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                            Path name = file.getFileName();
                            if (name != null && matcher.matches(name)) {
                                System.out.println("Searched file was found: " + name + " in " + file.toRealPath().toString());
                                List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
                                for (String line : lines) {

                                    Matcher regexMatcher = regex.matcher(line);
                                    if (regexMatcher.find()) {
                                        String wvdsrc = file.toRealPath().toString();
                                        if (wvdsrc.startsWith("/web/")) {
                                            wvdsrc = "/~./" + wvdsrc.replaceFirst("/web/", "");
                                        } 
                                        String wvdname = wvdsrc;
                                        if(wvdsrc.lastIndexOf("/") != -1) {
                                            wvdname = wvdsrc.substring(wvdsrc.lastIndexOf("/")+1);
                                        }


                                        String domainContextStr = regexMatcher.group(1);
                                        List<String> domainContextList = new ArrayList<>();
                                        if(domainContextStr.lastIndexOf(",") != -1) {
                                            domainContextList.add(domainContextStr);
                                        } else {
                                            domainContextList.addAll(Arrays.asList(domainContextStr.split(",")));
                                        }
                                        zuls.add(new WebViewDescriptor(wvdsrc, wvdname, domainContextList));
                                        break;
                                    }
                                }

                            }
                            return FileVisitResult.CONTINUE;
                        }

                        @Override
                        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                            return FileVisitResult.CONTINUE;
                        }

                        @Override
                        public FileVisitResult postVisitDirectory(Path dir, IOException ioe) {
                            return FileVisitResult.CONTINUE;
                        }
                    });
                }

            } catch (Exception ex) {
                Log.warn(ex, getClass(), "Couldn't parse "+ filePath);
            }

        }

    }

    init = true;

}

}

I hope this helps somebody else who needs to find all zuls in the classpath.

The WebViewDescriptor class is:

public class WebViewDescriptor {

private final String src;
private final String name;
private final List<String> domainContext;


public WebViewDescriptor(String src, String name, List<String> domainContext) {
    super();
    this.src = src;
    this.name = name;
    this.domainContext = domainContext;
}

public String getSrc() {
    return src;
}

public String getName() {
    return name;
}

public List<String> getDomainContext() {
    return domainContext;
}



@Override
public String toString() {
    return "WebViewDescriptor [src=" + src + ", name=" + name + ", domainContext=" + domainContext + "]";
}

}

Hi cor3000,

Thanks for the quick response.

Although I personally would have chosen one of your solutions my requirements were to make the developers job very easy, so to add a metadata in a zul file like:

<?viewDescriptor domainContext="user"?>

was the most simple thing and somehow equivalent to a java annotation. Your solution implies some extra work to do : to add a linked java class to the zul or to add some configuration in lang-addon to define the macro.

So it has been decided to follow the solution with adding some processing instruction to zuls .

The discovery of the zuls is something like this:

public class Factory {

private static final Factory instance = new Factory();
private List<WebViewDescriptor> zuls = new ArrayList<>();
private boolean init = false;
Pattern regex = Pattern.compile("<\\?viewDescriptor.+domainContext=\"(.*)\".*\\?>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
boolean IS_WINDOWS = System.getProperty("os.name").contains("indow");

public static Factory getInstance() {
    return instance;
}

public synchronized List<WebViewDescriptor> getAvailableZuls() {
    if (!init) {
        try {
            discover();
        } catch (Exception e) {
            Log.error(e, getClass(), "Error initializing web view descriptors");
        }
    }
    return zuls;

}

@SuppressWarnings("unchecked")
public synchronized void discover() throws Exception {

    // webapp including WEB-INF/classes
    String webapp = Sessions.getCurrent().getWebApp().getServletContext().getRealPath("/").replaceAll("\\\\", "\\\\\\\\");
    Collection<File> listFiles = FileUtils.listFiles(new File(webapp), new String[] { "zul" }, true);
    for (File f : listFiles) {

        List<String> lines = Files.readAllLines(Paths.get(f.getAbsolutePath()), StandardCharsets.UTF_8);
        for (String line : lines) {

            Matcher regexMatcher = regex.matcher(line);
            if (regexMatcher.find()) {
                String src = f.getAbsolutePath().replaceFirst(webapp, "").replaceAll("\\\\", "/");
                if (src.startsWith("WEB-INF/classes/web/")) {
                    src = "/~./" + src.replaceFirst("WEB-INF/classes/web/", "");
                } else if (src.startsWith("WEB-INF")) {
                    src = "/" + src;
                }
                String name = src;
                if(src.lastIndexOf("/") != -1) {
                    name = src.substring(src.lastIndexOf("/")+1);
                }


                String domainContextStr = regexMatcher.group(1);
                List<String> domainContextList = new ArrayList<>();
                if(domainContextStr.lastIndexOf(",") != == -1) {
                    domainContextList.add(domainContextStr);
                } else {
                    domainContextList.addAll(Arrays.asList(domainContextStr.split(",")));
                }
                zuls.add(new WebViewDescriptor(src, name, domainContextList));
                break;
            }
        }
    }

    // jars WEB-INF/lib/
    //if we also need other folders we need a recursive method while(classLoader.getParent() != null)

    ClassLoader classLoader = getClass().getClassLoader();
    URL[] urls = ((URLClassLoader) classLoader).getURLs();
    for (int i = 0 ; i < urls.length; i++) {

        String filePath = urls[i].getPath();
        filePath = IS_WINDOWS ? filePath.substring(1) : filePath;
        filePath = URLDecoder.decode(filePath, "UTF-8");
        if(filePath.endsWith(".jar")) {
            try (FileSystem fs = FileSystems.newFileSystem(Paths.get(filePath), null)) {
                Iterable<Path> dirs = fs.getRootDirectories();

                for (Path root : dirs) {
                    Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
                        private final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.{zul}");

                        @Override
                        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                            Path name = file.getFileName();
                            if (name != null && matcher.matches(name)) {
                                System.out.println("Searched file was found: " + name + " in " + file.toRealPath().toString());
                                List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
                                for (String line : lines) {

                                    Matcher regexMatcher = regex.matcher(line);
                                    if (regexMatcher.find()) {
                                        String wvdsrc = file.toRealPath().toString();
                                        if (wvdsrc.startsWith("/web/")) {
                                            wvdsrc = "/~./" + wvdsrc.replaceFirst("/web/", "");
                                        } 
                                        String wvdname = wvdsrc;
                                        if(wvdsrc.lastIndexOf("/") != -1) {
                                            wvdname = wvdsrc.substring(wvdsrc.lastIndexOf("/")+1);
                                        }


                                        String domainContextStr = regexMatcher.group(1);
                                        List<String> domainContextList = new ArrayList<>();
                                        if(domainContextStr.lastIndexOf(",") != == -1) {
                                            domainContextList.add(domainContextStr);
                                        } else {
                                            domainContextList.addAll(Arrays.asList(domainContextStr.split(",")));
                                        }
                                        zuls.add(new WebViewDescriptor(wvdsrc, wvdname, domainContextList));
                                        break;
                                    }
                                }

                            }
                            return FileVisitResult.CONTINUE;
                        }

                        @Override
                        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                            return FileVisitResult.CONTINUE;
                        }

                        @Override
                        public FileVisitResult postVisitDirectory(Path dir, IOException ioe) {
                            return FileVisitResult.CONTINUE;
                        }
                    });
                }

            } catch (Exception ex) {
                Log.warn(ex, getClass(), "Couldn't parse "+ filePath);
            }

        }

    }

    init = true;

}

}

I hope this helps somebody else who needs to find all zuls in the classpath.

The WebViewDescriptor class is:

public class WebViewDescriptor {

private final String src;
private final String name;
private final List<String> domainContext;


public WebViewDescriptor(String src, String name, List<String> domainContext) {
    super();
    this.src = src;
    this.name = name;
    this.domainContext = domainContext;
}

public String getSrc() {
    return src;
}

public String getName() {
    return name;
}

public List<String> getDomainContext() {
    return domainContext;
}



@Override
public String toString() {
    return "WebViewDescriptor [src=" + src + ", name=" + name + ", domainContext=" + domainContext + "]";
}

}

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More