All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.codename1.maven.GenerateGuiSourcesMojo Maven / Gradle / Ivy
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.codename1.maven;
import com.codename1.build.client.GenerateGuiSources;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.LinkedList;
import java.util.function.Function;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.surefire.shared.io.FileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import static com.codename1.maven.PathUtil.path;
/**
* Goal to generate java sources from the guibuilder files.
* @author shannah
*/
@Mojo(name="generate-gui-sources", defaultPhase = LifecyclePhase.INITIALIZE)
public class GenerateGuiSourcesMojo extends AbstractCN1Mojo {
@Override
protected void executeImpl() throws MojoExecutionException, MojoFailureException {
if (!isCN1ProjectDir()) {
return;
}
if (System.getProperty("generate-gui-sources-done") != null) {
return;
}
System.setProperty("generate-gui-sources-done", "true");
System.setProperty("javax.xml.bind.context.factory", "com.sun.xml.bind.v2.ContextFactory");
GenerateGuiSources g = new GenerateGuiSources();
g.setSrcDir(new File(getCN1ProjectDir(), "src" + File.separator + "main" + File.separator + "java"));
g.setGuiDir(new File(getCN1ProjectDir(), "src" + File.separator + "main" + File.separator + "guibuilder"));
g.execute();
// Generate the RAD templates while we're at it
File radViews = getRADViewsDirectory();
getLog().debug("Looking for views in "+radViews);
if (radViews.isDirectory()) {
project.addCompileSourceRoot(getRADGeneratedSourcesDirectory().getAbsolutePath());
Exception res = forEach(radViews, child -> {
if (!child.getName().endsWith(".xml")) {
return null;
}
File destClassFile = getDestClassForRADView(child);
getLog().debug("Found view "+child+". Checking against "+destClassFile);
if (!destClassFile.exists() || child.lastModified() > destClassFile.lastModified()) {
try {
generateRADViewClass(child);
} catch (IOException ex) {
return new MojoFailureException("Failed to generate class for RAD fragment XML file "+child, ex);
}
}
return null;
});
if (res != null) {
if (res instanceof MojoExecutionException) {
throw (MojoFailureException) res;
} else {
throw new MojoFailureException("Failed to compile RAD views:" + res.getMessage(), res);
}
}
}
}
private File getRADViewsDirectory() {
return new File(getCN1ProjectDir(), path("src", "main", "rad", "views"));
}
private File getRADGeneratedSourcesDirectory() {
return new File(path(project.getBuild().getDirectory(), "generated-sources" , "rad-views"));
}
private static Exception forEach(File root, Function callback) {
Exception res = callback.apply(root);
if (res != null) return res;
if (root.isDirectory()) {
for (File child : root.listFiles()) {
res = forEach(child, callback);
if (res != null) return res;
}
}
return null;
}
private File getDestClassForRADView(File viewXMLFile) {
String ext = viewXMLFile.getName().substring(viewXMLFile.getName().lastIndexOf("."));
String base = viewXMLFile.getName().substring(0, viewXMLFile.getName().lastIndexOf("."));
File viewsDirectory = getRADViewsDirectory();
int levels = 0;
LinkedList pathParts = new LinkedList();
File f = viewXMLFile.getParentFile();
while (f != null && !f.equals(viewsDirectory)) {
pathParts.addFirst(f.getName());
f = f.getParentFile();
}
StringBuilder pathSb = new StringBuilder();
for (String part : pathParts) {
pathSb.append(part).append(File.separator);
}
File genSrcDir = new File(getRADGeneratedSourcesDirectory(), pathSb.substring(0, pathSb.length()-1));
File out = new File(genSrcDir, base + ".java");
out = new File(out.getParentFile(), "Abstract" + out.getName());
return out;
}
private String getPackageForRADView(File viewXMLFile) {
String ext = viewXMLFile.getName().substring(viewXMLFile.getName().lastIndexOf("."));
String base = viewXMLFile.getName().substring(0, viewXMLFile.getName().lastIndexOf("."));
File viewsDirectory = getRADViewsDirectory();
int levels = 0;
LinkedList pathParts = new LinkedList();
File f = viewXMLFile.getParentFile();
while (f != null && !f.equals(viewsDirectory)) {
pathParts.addFirst(f.getName());
f = f.getParentFile();
}
StringBuilder pathSb = new StringBuilder();
for (String part : pathParts) {
pathSb.append(part).append(".");
}
return pathSb.substring(0, pathSb.length()-1);
}
private void generateRADViewClass(File xmlViewFile) throws IOException {
parentEntityViewClass = "AbstractEntityView";
viewModelType = "Entity";
getLog().debug("Generating RAD View for XML template "+xmlViewFile);
StringBuilder sb = new StringBuilder();
String packageName = getPackageForRADView(xmlViewFile);
String className = xmlViewFile.getName().substring(0, xmlViewFile.getName().indexOf("."));
className = "Abstract" + className;
String radViewString = FileUtils.readFileToString(xmlViewFile, "utf-8");
generateSchemaFor(xmlViewFile, radViewString);
radViewString = addElementIdentifiersToXML(radViewString);
if (!packageName.isEmpty()) {
sb.append("package ").append(packageName).append(";\n");
}
sb.append("import com.codename1.rad.annotations.RAD;\n");
sb.append("import com.codename1.rad.ui.AbstractEntityView;\n");
sb.append("import com.codename1.rad.ui.EntityView;\n");
sb.append("import com.codename1.rad.models.Entity;\n");
sb.append("import com.codename1.rad.nodes.Node;\n");
sb.append("import com.codename1.io.CharArrayReader;\n");
sb.append("import com.codename1.rad.ui.ViewContext;\n");
sb.append(importStatements);
sb.append("@RAD\n");
String parentClassName = parentEntityViewClass;
if (parentClassName.equals("AbstractEntityView")) {
parentClassName += "";
}
sb.append("public abstract class ").append(className).append(" extends ").append(parentClassName).append(" {\n");
sb.append(" private static final String FRAGMENT_XML=\"");
sb.append(StringEscapeUtils.escapeJava(radViewString));
sb.append("\";\n");
sb.append(" public ").append(className).append("(ViewContext context) {\n");
sb.append(" super(context);\n");
sb.append(" }\n\n");
sb.append("}\n");
File destFile = getDestClassForRADView(xmlViewFile);
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
getLog().debug("Updating "+destFile);
FileUtils.writeStringToFile(destFile, sb.toString(), "utf-8");
}
private static final String RAD_XML_NAMESPACE = "http://www.codenameone.com/rad";
private String parentEntityViewClass = "AbstractEntityView";
private String viewModelType = "Entity";
private void generateSchemaFor(File xmlViewFile, String contents) throws IOException {
File generatedSources = new File(getCN1ProjectDir(), path("target", "generated-sources"));
File xmlSchemasDirectory = new File(generatedSources, "rad" + File.separator + "xmlSchemas");
String packageName = getPackageForRADView(xmlViewFile);
String baseName = xmlViewFile.getName();
baseName = baseName.substring(0, baseName.lastIndexOf("."));
File actualXsdFile = new File(xmlSchemasDirectory, packageName.replace('.', File.separatorChar) + File.separator + baseName + ".xsd");
File xsdAliasFile = new File(xmlViewFile.getParentFile(), baseName + ".xsd");
if (!xsdAliasFile.exists()) {
StringBuilder sb = new StringBuilder();
sb.append("\n");
sb.append("\n");
sb.append(" \n");
sb.append(" \n");
getLog().info("Writing XSD alias file at "+xsdAliasFile);
FileUtils.writeStringToFile(xsdAliasFile, sb.toString(), "UTF-8");
}
if (!contents.contains("xsi:noNamespaceSchemaLocation=\"") || !contents.contains("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")) {
int rootTagStart = contents.indexOf("?>");
if (rootTagStart < 0) {
getLog().info("Not adding schema declaration to "+xmlViewFile+" because it failed to find the root element. The file may be malformed.");
return;
}
rootTagStart = contents.indexOf("<", rootTagStart);
if (rootTagStart < 0) {
getLog().info("Not adding schema declaration to "+xmlViewFile+" because it failed to find the root element. The file may be malformed.");
return;
}
int rootTagEnd = contents.indexOf(">", rootTagStart);
if (rootTagEnd < 0) {
getLog().info("Not adding schema declaration to "+xmlViewFile+" because it failed to find the close of the root element. The file may be malformed.");
}
String toInject = !contents.contains("xsi:noNamespaceSchemaLocation=\"") ? " xsi:noNamespaceSchemaLocation=\"" + baseName + ".xsd\"" : "";
if (!contents.contains("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")) {
toInject += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
}
if (!contents.substring(0, rootTagEnd).contains("xsi:xsi:noNamespaceSchemaLocation") || !contents.substring(0, rootTagEnd).contains("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")) {
contents = contents.substring(0, rootTagEnd) + toInject + contents.substring(rootTagEnd);
FileUtils.writeStringToFile(xmlViewFile, contents, "utf-8");
getLog().info("Injected schema declaration into document element of " + xmlViewFile);
}
}
}
private StringBuilder importStatements = new StringBuilder();
private String addElementIdentifiersToXML(String xml) throws IOException {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//an instance of builder to parse the specified xml file
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(xml.getBytes("utf-8")));
class Context {
int index=0;
void crawl(org.w3c.dom.Element el) {
if (index == 0) {
if (el.hasAttribute("rad-extends")) {
parentEntityViewClass = el.getAttribute("rad-extends");
}
if (el.hasAttribute("rad-model")) {
viewModelType = el.getAttribute("rad-model");
}
}
if (el.getTagName().equalsIgnoreCase("import")) {
importStatements.append(el.getTextContent()).append("\n");
}
el.setAttribute("rad-id", String.valueOf(index++));
NodeList children = el.getChildNodes();
int len = children.getLength();
for (int i=0; i