use of com.codename1.rad.annotations.RAD in project CodenameOne by codenameone.
the class GenerateGuiSourcesMojo method executeImpl.
@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);
}
}
}
}
use of com.codename1.rad.annotations.RAD in project CodenameOne by codenameone.
the class ProjectTemplate method convertToTemplate.
/**
* Convert a real project to a template.
* This mainly consists changing all references to the specified packageName and mainName
* to be changed the the ${packageName} and ${mainName} variables.
*
* @param packageName
* @param mainName
*/
public void convertToTemplate(String packageName, String mainName) throws IOException {
File codenameOneSettings = new File(projectRoot, "codenameone_settings.properties");
SortedProperties settingsProps = new SortedProperties();
String path;
if (codenameOneSettings.exists()) {
// This is an ant project
try (FileInputStream fis = new FileInputStream(codenameOneSettings)) {
settingsProps.load(fis);
}
settingsProps.put("codename1.packageName", "${packageName}");
settingsProps.put("codename1.mainName", "${mainName}");
try (FileOutputStream fos = new FileOutputStream(codenameOneSettings)) {
settingsProps.store(fos, "Updated packageName and mainName");
}
File srcDir = new File(projectRoot, "src");
if (srcDir.exists()) {
convertToTemplate(packageName, mainName, srcDir);
}
path = packageName.replace('.', File.separatorChar);
File packageDirectory = new File(srcDir, path);
if (packageDirectory.exists()) {
File dest = new File(srcDir, "__packagePath__");
FileUtils.moveDirectory(packageDirectory, dest);
for (File child : dest.listFiles()) {
if (child.getName().equals(mainName + ".java") || child.getName().equals(mainName + ".kt") || child.getName().equals(mainName + ".mirah")) {
File destMain = new File(dest, "__mainName__" + child.getName().substring(child.getName().lastIndexOf(".")));
FileUtils.moveFile(child, destMain);
}
}
convertToTemplate(packageName, mainName, dest);
}
return;
}
codenameOneSettings = new File(projectRoot, path("common", "codenameone_settings.properties"));
if (codenameOneSettings.exists()) {
// This is a maven project.
try (FileInputStream fis = new FileInputStream(codenameOneSettings)) {
settingsProps.load(fis);
}
settingsProps.put("codename1.packageName", "${packageName}");
settingsProps.put("codename1.mainName", "${mainName}");
try (FileOutputStream fos = new FileOutputStream(codenameOneSettings)) {
settingsProps.store(fos, "Updated packageName and mainName");
}
for (String lang : new String[] { "java", "kotlin", "mirah", "resources", "rad" + File.separator + "views" }) {
File srcDir = new File(codenameOneSettings.getParentFile(), path("src", "main", lang));
if (srcDir.exists()) {
convertToTemplate(packageName, mainName, srcDir);
}
path = packageName.replace('.', File.separatorChar);
File packageDirectory = new File(srcDir, path);
if (packageDirectory.exists()) {
File dest = new File(srcDir, "__packagePath__");
FileUtils.moveDirectory(packageDirectory, dest);
for (File child : dest.listFiles()) {
if (child.getName().equals(mainName + ".java") || child.getName().equals(mainName + ".kt") || child.getName().equals(mainName + ".mirah")) {
File destMain = new File(dest, "__mainName__" + child.getName().substring(child.getName().lastIndexOf(".")));
FileUtils.moveFile(child, destMain);
}
}
convertToTemplate(packageName, mainName, dest);
}
}
return;
}
}
use of com.codename1.rad.annotations.RAD in project CodenameOne by codenameone.
the class RADActionBoundUIIDSample method start.
public void start() {
if (current != null) {
current.show();
return;
}
Form hi = new Form("Toggled Actions Sample", new BorderLayout());
// Create a tag fo the online status property.
Tag TAG_ONLINE = new Tag("online");
// Create an action that will indicte the online/offline status
ActionNode status = UI.action(// on state of TAG_ONLINE property.
UI.label(person -> {
if (person.isFalsey(TAG_ONLINE)) {
return "Offline";
} else {
return "Online";
}
}), // Depending on state of TAG_ONLINE property
UI.uiid(person -> {
if (person.isFalsey(TAG_ONLINE)) {
return "LoggedOutStatusButton";
} else {
return "LoggedInStatusButton";
}
}), // Icon for the action
UI.icon(FontImage.MATERIAL_PERSON), // define it to always return true so action is always visible.
UI.condition(person -> {
return true;
}));
// A User entity we use for the models.
class User extends Entity {
}
entityTypeBuilder(User.class).Boolean(TAG_ONLINE).string(Thing.name).factory(cls -> {
return new User();
}).build();
// Create an entity list that will hold several users.
EntityList el = new EntityList();
for (int i = 0; i < 200; i++) {
User u = new User();
u.set(Thing.name, "User " + i);
u.set(TAG_ONLINE, i % 2 == 0);
el.add(u);
}
// The ListNode is a wrapper that will be passed to our View so that
// they can access our action.
ListNode node = new ListNode(// for each row.
UI.actions(ProfileListView.ACCOUNT_LIST_ROW_ACTIONS, status));
// Use a ProfileListView to display all of the users
// https://shannah.github.io/CodeRAD/javadoc/com/codename1/rad/ui/entityviews/ProfileListView.html
ProfileListView plv = new ProfileListView(el, node, 8);
plv.setScrollableY(true);
// In order to respond to events raised by the action, our view needs to be wrapped
// in a controller. Normally our form would have a FormViewController so we could
// just use FormController, but this sample is compressed to be inside
// a single method here so we'll create a dedicated ViewController for the list
ViewController ctrl = new ViewController(null);
ctrl.setView(plv);
ctrl.addActionListener(status, evt -> {
// The action was pressed by the user
// Update the model's online status
User u = (User) evt.getEntity();
u.set(TAG_ONLINE, u.isFalsey(TAG_ONLINE));
// This will trigger a property change in the model which will update the view.
});
hi.add(CENTER, plv);
hi.show();
}
use of com.codename1.rad.annotations.RAD in project CodenameOne by codenameone.
the class RADEntityListAddRemoveInvalidateSample method start.
public void start() {
if (current != null) {
current.show();
return;
}
// An entity for the rows our our list view.
class Person extends Entity {
}
entityTypeBuilder(Person.class).string(Thing.name).factory(cls -> {
return new Person();
}).build();
// A remove row action that will be added to each row
ActionNode removeRow = UI.action(UI.icon(FontImage.MATERIAL_DELETE));
// An internal list we will use to store the rows of the entitylist
ArrayList internalList = new ArrayList();
EntityList profileList = new EntityList() {
/**
* Override createInternalList() so that we can use our own data structure
* for storing this list. This is contrived to allow us to test the
* invalidate() method.
*/
@Override
protected List createInternalList() {
return internalList;
}
};
// A list node to wrap our action and pass it to our view
ListNode node = new ListNode(// of the list.
UI.actions(ProfileListView.ACCOUNT_LIST_ROW_ACTIONS, removeRow));
// A ProfileListView to render the list.
// See https://shannah.github.io/CodeRAD/javadoc/com/codename1/rad/ui/entityviews/ProfileListView.html
ProfileListView listView = new ProfileListView(profileList, node, 10);
listView.setScrollableY(true);
// Create a controller for the ProfileListView so that we can handle actions fired by the view.
// Normally we'd do this in the FormController but since this sample doesn't have one
// we create a ViewController for the ProfileListView directly.
ViewController controller = new ViewController(null);
controller.setView(listView);
// Button to add rows to the list
Button addRow = new Button(FontImage.MATERIAL_ADD);
// Button to clear the list
Button clear = new Button("Clear");
addRow.addActionListener(evt -> {
// "Add" button clicked.
// Create new person and add to the list
Person p = new Person();
p.set(Thing.name, "Row " + profileList.size());
profileList.add(p);
// This will trigger an EntityAddedEvent which will allow
// the ProfileListView to synchronize
});
clear.addActionListener(evt -> {
// "Clear" button clicked
// We could have called profileList.clear()
// but this would send EntityRemoved events for each row removed
// which is inefficient. Instead we'll clear the elements in
// the internal list directly, and then call invalidate()
// so that the ProfileListView knows to resynchronize its state.
internalList.clear();
profileList.invalidate();
});
controller.addActionListener(removeRow, evt -> {
// The "Remove" button was clicked on a row.
profileList.remove(evt.getEntity());
});
Form hi = new Form("Hi World", new BorderLayout());
hi.add(NORTH, GridLayout.encloseIn(2, clear, addRow));
hi.add(CENTER, listView);
hi.show();
}
use of com.codename1.rad.annotations.RAD in project CodeRAD by shannah.
the class XMLSchemaGenerator method writeSchema.
public StringBuilder writeSchema(StringBuilder sb, boolean writeHeader) throws IOException {
if (writeHeader) {
sb.append("<?xml version=\"1.0\"?>\n");
alreadyIncludedSet.clear();
}
if (writeElements) {
sb.append("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n");
}
if (checksum != null)
sb.append("<!-- ").append(checksum).append(" -->\n");
indent += 2;
for (File includeFile : includes) {
// String id = includeFile.getAbsolutePath().replace(".", "_").replace(File.separatorChar, '_').replace("/", "_");
String content;
try (FileInputStream fis = new FileInputStream(includeFile)) {
byte[] bytes = new byte[(int) includeFile.length()];
fis.read(bytes);
content = new String(bytes, "UTF-8");
}
content = content.trim();
if (content.startsWith("====\n")) {
// There is head matter
int headMatterEndPos = content.indexOf("====\n", 5);
if (headMatterEndPos < 0) {
throw new IOException("Invalid content found in file " + includeFile + ". Found head matter with no end separator.");
}
String headMatter = content.substring(5, headMatterEndPos + 5).trim();
content = content.substring(headMatterEndPos + 5).trim();
if (content.startsWith("<?xml")) {
content = content.substring(content.indexOf("?>") + 2).trim();
}
StringTokenizer strtok = new StringTokenizer(headMatter, "\n");
while (strtok.hasMoreTokens()) {
String nextTok = strtok.nextToken().trim();
if (nextTok.startsWith("requireAttributeGroup ")) {
String attGroupCoords = nextTok.substring(nextTok.indexOf(" ") + 1);
String prefix = attGroupCoords.substring(0, attGroupCoords.indexOf(":"));
String type = attGroupCoords.substring(prefix.length() + 1, attGroupCoords.indexOf(":", prefix.length() + 1));
String depth = attGroupCoords.substring(attGroupCoords.lastIndexOf(":") + 1);
File attgroupFile = getAttributeGroupFile(new AttributeGroup(prefix, type, Integer.parseInt(depth)));
if (!attgroupFile.exists()) {
throw new IOException("Cannot find attribute group file at " + attgroupFile + " required by " + includeFile + " while processing schema for " + javaClass);
}
if (alreadyIncludedSet.contains(attgroupFile.getAbsolutePath())) {
continue;
}
alreadyIncludedSet.add(attgroupFile.getAbsolutePath());
try (FileInputStream fis = new FileInputStream(attgroupFile)) {
byte[] bytes = new byte[(int) attgroupFile.length()];
fis.read(bytes);
String tmp = new String(bytes, "UTF-8").trim();
if (tmp.startsWith("<?xml")) {
tmp = tmp.substring(tmp.indexOf("?>") + 2).trim();
}
content = tmp + "\n" + content;
}
} else if (nextTok.startsWith("require ")) {
TypeElement requiredType = processingEnvironment.getElementUtils().getTypeElement(nextTok.substring(nextTok.indexOf(" ") + 1).trim());
if (requiredType != null) {
File requiredTypeFile = getClassSchemaFile(requiredType);
if (!requiredTypeFile.exists()) {
throw new IOException("Cannot find type schema " + requiredTypeFile + " required by " + includeFile + " while processing schema for " + javaClass);
}
if (alreadyIncludedSet.contains(requiredType.getQualifiedName().toString())) {
continue;
}
alreadyIncludedSet.add(requiredType.getQualifiedName().toString());
// System.out.println("including "+requiredType);
try (FileInputStream fis = new FileInputStream(requiredTypeFile)) {
byte[] bytes = new byte[(int) requiredTypeFile.length()];
fis.read(bytes);
String tmp = new String(bytes, "UTF-8").trim();
if (tmp.startsWith("<?xml")) {
tmp = tmp.substring(tmp.indexOf("?>") + 2).trim();
}
content = tmp + "\n" + content;
}
}
}
}
} else {
if (content.startsWith("<?xml")) {
content = content.substring(content.indexOf("?>") + 2).trim();
}
}
indent(sb, indent).append(content).append("\n");
}
if (!writeElements) {
Set<Element> parentMembers = new HashSet<>();
String extensionBase = null;
TypeElement superType = null;
{
TypeMirror superclass = javaClass.getSuperclass();
if (superclass != null && superclass.getKind() == TypeKind.DECLARED) {
superType = (TypeElement) ((DeclaredType) superclass).asElement();
}
}
if (superType != null) {
extensionBase = superType.getQualifiedName().toString().replace('.', '_');
final TypeElement fSuperType = superType;
final DeclaredType fDeclaredSuperType = (DeclaredType) fSuperType.asType();
processingEnvironment.getElementUtils().getAllMembers(superType).forEach(e -> {
if (e.getKind() == ElementKind.METHOD && e.getSimpleName().toString().startsWith("get")) {
TypeMirror tm = processingEnvironment.getTypeUtils().asMemberOf(fDeclaredSuperType, e);
if (tm.getKind() == TypeKind.EXECUTABLE) {
ExecutableType methodMirror = (ExecutableType) tm;
TypeMirror methodReturnType = methodMirror.getReturnType();
if (methodReturnType.getKind() == TypeKind.TYPEVAR || methodReturnType.getKind() == TypeKind.WILDCARD) {
return;
}
}
}
parentMembers.add(e);
});
}
String complexTypeName = javaClass.getQualifiedName().toString().replace('.', '_');
Set<String> attributeNames = new HashSet<>();
for (TypeElement clazz : new TypeElement[] { javaClass, builderClass }) {
if (clazz == null) {
// The builder class is null
indent(sb, indent).append("<xs:complexType name=\"").append(complexTypeName).append("-impl\">\n");
indent(sb, indent).append(" <xs:complexContent>\n");
indent(sb, indent).append(" <xs:extension base=\"").append(complexTypeName).append("\"/>\n");
indent(sb, indent).append(" </xs:complexContent>\n");
indent(sb, indent).append("</xs:complexType>\n");
continue;
}
if (clazz == builderClass) {
indent(sb, indent).append("<xs:complexType name=\"").append(complexTypeName).append("-impl\">\n");
indent += 2;
indent(sb, indent).append("<xs:complexContent>\n");
indent += 2;
indent(sb, indent).append("<xs:extension base=\"").append(complexTypeName).append("\">\n");
indent += 2;
} else {
String mixed = extensionBase != null ? "" : " mixed=\"true\"";
indent(sb, indent).append("<xs:complexType name=\"").append(complexTypeName).append("\"").append(mixed).append(">\n");
indent += 2;
if (extensionBase != null) {
indent(sb, indent).append("<xs:complexContent>\n");
indent += 2;
indent(sb, indent).append("<xs:extension base=\"").append(extensionBase).append("\">\n");
indent += 2;
} else {
indent(sb, indent).append("<xs:sequence><xs:any minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\"/></xs:sequence>");
indent(sb, indent).append("<xs:attribute name=\"layout-constraint\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"layout-rows\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"layout-columns\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-transition\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-leadComponent\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-implements\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-href\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-href-trigger\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"view-model\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"view-controller\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-extends\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-model\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-var\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-property\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"rad-condition\" type=\"xs:string\"/>\n");
}
}
if (clazz.getQualifiedName().contentEquals("com.codename1.ui.Component")) {
TypeElement componentBinder = processingEnvironment.getElementUtils().getTypeElement("com.codename1.rad.ui.builders.ComponentBinder");
for (Element member : processingEnvironment.getElementUtils().getAllMembers(componentBinder)) {
if (member.getKind() == ElementKind.METHOD && member.getSimpleName().toString().startsWith("bind")) {
String propertyName = toCamelCase(member.getSimpleName().toString().substring(4));
indent(sb, indent).append("<xs:attribute name=\"bind-").append(propertyName).append("\" type=\"xs:string\"/>\n");
}
}
}
for (Element member : processingEnvironment.getElementUtils().getAllMembers(clazz)) {
if (extensionBase != null && parentMembers.contains(member))
continue;
if (member.getKind() == ElementKind.METHOD) {
ExecutableElement methodEl = (ExecutableElement) member;
if (methodEl.getParameters().size() == 1) {
// Could be a setter
String methodName = methodEl.getSimpleName().toString();
String propertyName = methodName;
if (clazz == javaClass && !methodName.startsWith("set")) {
continue;
}
if (clazz == builderClass && !methodName.startsWith("set")) {
ExecutableType methodType = (ExecutableType) processingEnvironment.getTypeUtils().asMemberOf((DeclaredType) builderClass.asType(), methodEl);
if (!env.isA(methodType.getReturnType(), "com.codename1.rad.ui.ComponentBuilder")) {
// a builder style method that returns the builder for chaining.
continue;
}
}
if (methodName.startsWith("set")) {
propertyName = propertyName.substring(3);
}
if (propertyName.isEmpty())
continue;
propertyName = toCamelCase(propertyName);
if (attributeNames.contains(propertyName.toLowerCase()))
continue;
attributeNames.add(propertyName.toLowerCase());
TypeMirror paramTypeMirror = methodEl.getParameters().get(0).asType();
List<String> enumValues = null;
TypeElement parameterType = null;
if (paramTypeMirror.getKind() == TypeKind.DECLARED) {
parameterType = (TypeElement) ((DeclaredType) paramTypeMirror).asElement();
enumValues = parameterType.getEnclosedElements().stream().filter(element -> element.getKind().equals(ElementKind.ENUM_CONSTANT)).map(Object::toString).collect(Collectors.toList());
}
String type = "xs:string";
if (enumValues != null && !enumValues.isEmpty()) {
type = parameterType.getQualifiedName().toString().replace('.', '_');
enumTypes.add(parameterType);
}
indent(sb, indent).append("<xs:attribute name=\"").append(propertyName).append("\" type=\"").append(type).append("\"/>\n");
if (clazz == javaClass) {
indent(sb, indent).append("<xs:attribute name=\"").append("bind-" + propertyName).append("\" type=\"xs:string\"/>\n");
}
} else if (clazz == javaClass && methodEl.getParameters().size() == 0 && methodEl.getSimpleName().toString().startsWith("get")) {
boolean useAttributeGroups = true;
ExecutableType methodType = (ExecutableType) processingEnvironment.getTypeUtils().asMemberOf((DeclaredType) clazz.asType(), methodEl);
String propertyName = toCamelCase(methodEl.getSimpleName().toString().substring(3));
if (methodType != null && methodType.getReturnType() != null) {
if (env.isA(methodType.getReturnType(), "com.codename1.ui.plaf.Style") || methodEl.getSimpleName().contentEquals("getComponentForm") || methodEl.getSimpleName().contentEquals("getParent") || env.isA(methodType.getReturnType(), "com.codename1.rad.nodes.ActionNode.Builder") || (methodEl.getAnnotation(RADDoc.class) != null && methodEl.getAnnotation(RADDoc.class).generateSubattributeHints() && methodType.getReturnType().getKind() == TypeKind.DECLARED)) {
TypeMirror retTypeMirror = methodType.getReturnType();
if (retTypeMirror.getKind() == TypeKind.DECLARED) {
// processingEnvironment.getElementUtils().getTypeElement("com.codename1.ui.plaf.Style");
TypeElement retType = (TypeElement) ((DeclaredType) retTypeMirror).asElement();
if (useAttributeGroups) {
indent(sb, indent).append("<xs:attributeGroup ref=\"").append(getAttributeGroupName((DeclaredType) retTypeMirror, propertyName + ".", 1)).append("\" />\n");
addRequiredAttributeGroup(new AttributeGroup(propertyName + ".", retType.getQualifiedName().toString(), 1));
} else {
for (Element subMember : processingEnvironment.getElementUtils().getAllMembers(retType)) {
String subMethodName = subMember.getSimpleName().toString();
if (subMember.getKind() != ElementKind.METHOD)
continue;
if (!subMethodName.startsWith("set"))
continue;
if (((ExecutableElement) subMember).getParameters().size() != 1)
continue;
List<String> enumValues = null;
TypeElement parameterType = null;
TypeMirror parameterTypeMirror = ((ExecutableElement) subMember).getParameters().get(0).asType();
if (parameterTypeMirror.getKind() == TypeKind.DECLARED) {
parameterType = (TypeElement) ((DeclaredType) parameterTypeMirror).asElement();
enumValues = parameterType.getEnclosedElements().stream().filter(element -> element.getKind().equals(ElementKind.ENUM_CONSTANT)).map(Object::toString).collect(Collectors.toList());
}
String type = "xs:string";
if (enumValues != null && !enumValues.isEmpty()) {
type = parameterType.toString().replace('.', '_');
enumTypes.add(parameterType);
}
indent(sb, indent).append("<xs:attribute name=\"").append(propertyName).append(".").append(toCamelCase(subMethodName.toString().substring(3))).append("\" type=\"").append(type).append("\"/>\n");
indent(sb, indent).append("<xs:attribute name=\"bind-").append(propertyName).append(".").append(toCamelCase(subMethodName.toString().substring(3))).append("\" type=\"xs:string\"/>\n");
}
}
}
}
}
}
}
}
if (clazz == builderClass || extensionBase != null) {
indent -= 2;
indent(sb, indent).append("</xs:extension>\n");
indent -= 2;
indent(sb, indent).append("</xs:complexContent>\n");
}
indent -= 2;
indent(sb, indent).append("</xs:complexType>\n");
}
for (XMLSchemaGenerator subGenerator : subGenerators) {
subGenerator.writeSchema(sb, false);
}
}
if (writeElements) {
indent(sb, indent).append("<xs:element name=\"script\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:element name=\"import\" type=\"xs:string\"/>\n");
indent(sb, indent).append("<xs:element name=\"view-model\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:sequence>\n");
indent(sb, indent).append(" <xs:element ref=\"define-property\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n");
indent(sb, indent).append(" </xs:sequence>\n");
indent(sb, indent).append(" <xs:attribute name=\"extends\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"implements\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"form-controller\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"extends\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"implements\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"view-controller\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"extends\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"bind-action\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"category\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"inherit\" type=\"xs:boolean\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"on\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"define-tag\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"name\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"value\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"type\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"initialValue\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"use-taglib\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"package\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"class\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"define-property\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"name\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"type\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"initialValue\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"define-category\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"name\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"value\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"var\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:attribute name=\"value\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"lookup\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"name\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" <xs:attribute name=\"type\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"define-slot\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:sequence>\n");
indent(sb, indent).append(" <xs:any minOccurs=\"0\" maxOccurs=\"1\" />\n");
indent(sb, indent).append(" </xs:sequence>\n");
indent(sb, indent).append(" <xs:attribute name=\"id\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"fill-slot\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:sequence>\n");
indent(sb, indent).append(" <xs:any minOccurs=\"0\" maxOccurs=\"1\"/>\n");
indent(sb, indent).append(" </xs:sequence>\n");
indent(sb, indent).append(" <xs:attribute name=\"id\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
indent(sb, indent).append("<xs:element name=\"row-template\">\n");
indent(sb, indent).append(" <xs:complexType>\n");
indent(sb, indent).append(" <xs:sequence>\n");
indent(sb, indent).append(" <xs:any minOccurs=\"0\" maxOccurs=\"1\"/>\n");
indent(sb, indent).append(" </xs:sequence>\n");
indent(sb, indent).append(" <xs:attribute name=\"case\" type=\"xs:string\"/>\n");
indent(sb, indent).append(" </xs:complexType>\n");
indent(sb, indent).append("</xs:element>\n");
for (Map.Entry<String, TypeElement> e : allTags.entrySet()) {
if (e.getValue().getModifiers().contains(Modifier.PUBLIC) && !e.getValue().getModifiers().contains(Modifier.ABSTRACT)) {
indent(sb, indent).append("<xs:element name=\"").append(e.getKey()).append("\" type=\"").append(e.getValue().getQualifiedName().toString().replace('.', '_')).append("-impl\"/>\n");
}
}
}
if (writeElements) {
indent -= 2;
indent(sb, indent).append("</xs:schema>\n");
} else {
boolean includeHeadmatter = !requiredAttributeGroups.isEmpty() || !enumTypes.isEmpty();
StringBuilder headMatter = includeHeadmatter ? new StringBuilder() : null;
if (includeHeadmatter) {
headMatter.append("====\n");
}
if (!requiredAttributeGroups.isEmpty()) {
HashSet<AttributeGroup> currentRound = new HashSet<>(requiredAttributeGroups);
while (!currentRound.isEmpty()) {
for (AttributeGroup group : currentRound) {
headMatter.append("requireAttributeGroup ").append(group.prefix).append(":").append(group.type).append(":").append(group.depth).append("\n");
File attGroupFile = getAttributeGroupFile(group);
if (!attGroupFile.exists()) {
StringBuilder attGroupContent = new StringBuilder();
writeAttributeGroup(attGroupContent, (DeclaredType) env.lookupClass(group.type).asType(), group.prefix, group.depth);
attGroupFile.getParentFile().mkdirs();
try (FileOutputStream fos = new FileOutputStream(attGroupFile)) {
fos.write(attGroupContent.toString().getBytes("UTF-8"));
}
}
writtenAttributeGroups.add(group);
}
currentRound.clear();
currentRound.addAll(requiredAttributeGroups);
currentRound.removeAll(writtenAttributeGroups);
}
}
if (!enumTypes.isEmpty()) {
for (TypeElement enumType : enumTypes) {
headMatter.append("require ").append(enumType.getQualifiedName()).append("\n");
File enumSchemaFile = getClassSchemaFile(enumType);
if (!enumSchemaFile.exists()) {
enumSchemaFile.getParentFile().mkdirs();
StringBuilder enumSchemaContent = new StringBuilder();
writeEnumType(enumSchemaContent, enumType);
try (FileOutputStream fos = new FileOutputStream(enumSchemaFile)) {
fos.write(enumSchemaContent.toString().getBytes("UTF-8"));
}
}
}
}
if (includeHeadmatter) {
headMatter.append("====\n");
sb.insert(0, headMatter);
}
}
return sb;
}
Aggregations