-
FEATURED COMPONENTS
First time here? Check out the FAQ!
1 | initial version | |
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 + "]";
}
}
2 | No.2 Revision |
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 + "]";
}
}