use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class BlackBerryImplementation method nativeEdit.
public void nativeEdit(final Component cmp, final int maxSize, final int constraint, String text, int keyCode) {
if (nativeEdit != null) {
finishEdit(true);
}
lightweightEdit = (TextArea) cmp;
if (keyCode > 0 && getKeyboardType() == Display.KEYBOARD_TYPE_QWERTY) {
// if this is a number
if ((constraint & TextArea.DECIMAL) == TextArea.DECIMAL || (constraint & TextArea.NUMERIC) == TextArea.NUMERIC || (constraint & TextArea.PHONENUMBER) == TextArea.PHONENUMBER) {
if (keyCode == 119) {
text += "1";
} else if (keyCode == 101) {
text += "2";
} else if (keyCode == 114) {
text += "3";
} else if (keyCode == 115) {
text += "4";
} else if (keyCode == 100) {
text += "5";
} else if (keyCode == 102) {
text += "6";
} else if (keyCode == 122) {
text += "7";
} else if (keyCode == 120) {
text += "8";
} else if (keyCode == 99) {
text += "9";
}
} else {
text += ((char) keyCode);
}
lightweightEdit.setText(text);
}
class LightweightEdit implements Runnable, Animation {
public void run() {
long type = 0;
TextArea lightweightEditTmp = lightweightEdit;
if (lightweightEditTmp == null) {
return;
}
int constraint = lightweightEditTmp.getConstraint();
if ((constraint & TextArea.DECIMAL) == TextArea.DECIMAL) {
type = BasicEditField.FILTER_REAL_NUMERIC;
} else if ((constraint & TextArea.EMAILADDR) == TextArea.EMAILADDR) {
type = BasicEditField.FILTER_EMAIL;
} else if ((constraint & TextArea.NUMERIC) == TextArea.NUMERIC) {
type = BasicEditField.FILTER_NUMERIC;
}
if ((constraint & TextArea.PHONENUMBER) == TextArea.PHONENUMBER) {
type = BasicEditField.FILTER_PHONE;
}
if ((constraint & TextArea.NON_PREDICTIVE) == TextArea.NON_PREDICTIVE) {
type |= BasicEditField.NO_COMPLEX_INPUT;
}
if (lightweightEditTmp.isSingleLineTextArea()) {
type |= BasicEditField.NO_NEWLINE;
}
if ((constraint & TextArea.PASSWORD) == TextArea.PASSWORD) {
nativeEdit = new BBPasswordEditField(lightweightEditTmp, type, maxSize);
} else {
nativeEdit = new BBEditField(lightweightEditTmp, type, maxSize);
}
nativeEdit.setEditable(true);
Font f = nativeEdit.getFont();
if (f.getHeight() > lightweightEditTmp.getStyle().getFont().getHeight()) {
nativeEdit.setFont(f.derive(f.getStyle(), lightweightEditTmp.getStyle().getFont().getHeight()));
}
canvas.add(nativeEdit);
nativeEdit.setCursorPosition(lightweightEditTmp.getText().length());
try {
nativeEdit.setFocus();
} catch (Throwable t) {
// no idea why this throws an exception sometimes
// t.printStackTrace();
}
}
public boolean animate() {
BasicEditField ef = nativeEdit;
Component lw = lightweightEdit;
if (lw == null || lw.getComponentForm() != Display.getInstance().getCurrent()) {
Display.getInstance().getCurrent().deregisterAnimated(this);
finishEdit(false);
} else {
if (ef != null) {
if (ef.isDirty()) {
lw.repaint();
}
}
}
return false;
}
public void paint(com.codename1.ui.Graphics g) {
}
}
LightweightEdit lw = new LightweightEdit();
Display.getInstance().getCurrent().registerAnimated(lw);
Application.getApplication().invokeLater(lw);
}
use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class Container method insertComponentAt.
void insertComponentAt(final int index, final Object constraint, final Component cmp) {
final AnimationManager a = getAnimationManager();
if (a != null && a.isAnimating()) {
// pretend like the component was already added
if (cmp.getParent() != null) {
throw new IllegalArgumentException("Component is already contained in Container: " + cmp.getParent());
}
cmp.setParent(this);
final QueuedInsertion insertion = new QueuedInsertion(index, constraint, cmp);
changeQueue.add(insertion);
a.addAnimation(new ComponentAnimation() {
private boolean alreadyAdded;
@Override
public boolean isInProgress() {
return false;
}
@Override
protected void updateState() {
if (!alreadyAdded) {
try {
alreadyAdded = true;
cmp.setParent(null);
if (constraint != null) {
layout.addLayoutComponent(constraint, cmp, Container.this);
}
insertComponentAtImpl(index, cmp);
} finally {
changeQueue.remove(insertion);
}
revalidateLater();
}
}
@Override
public void flush() {
updateState();
}
});
} else {
if (constraint != null) {
layout.addLayoutComponent(constraint, cmp, this);
}
insertComponentAtImpl(index, cmp);
}
}
use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class IOSImplementation method editString.
public void editString(final Component cmp, final int maxSize, final int constraint, final String text, final int i) {
// The very first time we try to edit a string, let's determine if the
// system default is to do async editing. If the system default
// is not yet set, we set it here, and it will be used as the default from now on
// We do this because the nativeInstance.isAsyncEditMode() value changes
// to reflect the currently edited field so it isn't a good way to keep a
// system default.
pendingEditingText = false;
String defaultAsyncEditingSetting = Display.getInstance().getProperty("ios.VKBAlwaysOpen", null);
if (defaultAsyncEditingSetting == null) {
defaultAsyncEditingSetting = nativeInstance.isAsyncEditMode() ? "true" : "false";
Display.getInstance().setProperty("ios.VKBAlwaysOpen", defaultAsyncEditingSetting);
}
boolean asyncEdit = "true".equals(defaultAsyncEditingSetting) ? true : false;
try {
if (currentEditing != cmp && currentEditing != null && currentEditing instanceof TextArea) {
Display.getInstance().onEditingComplete(currentEditing, ((TextArea) currentEditing).getText());
currentEditing = null;
callHideTextEditor();
if (nativeInstance.isAsyncEditMode()) {
nativeInstance.setNativeEditingComponentVisible(false);
}
synchronized (EDITING_LOCK) {
EDITING_LOCK.notify();
}
Display.getInstance().callSerially(new Runnable() {
public void run() {
pendingEditingText = true;
Display.getInstance().editString(cmp, maxSize, constraint, text, i);
}
});
return;
}
if (cmp.isFocusable() && !cmp.hasFocus()) {
doNotHideTextEditorSemaphore++;
try {
cmp.requestFocus();
} finally {
doNotHideTextEditorSemaphore--;
}
// of our upcoming field.
if (isAsyncEditMode()) {
// flush the EDT so the focus will work...
Display.getInstance().callSerially(new Runnable() {
public void run() {
pendingEditingText = true;
Display.getInstance().editString(cmp, maxSize, constraint, text, i);
}
});
return;
}
}
// Check if the form has any setting for asyncEditing that should override
// the application defaults.
Form parentForm = cmp.getComponentForm();
if (parentForm == null) {
// Log.p("Attempt to edit text area that is not on a form. This is not supported");
return;
}
if (parentForm.getClientProperty("asyncEditing") != null) {
Object async = parentForm.getClientProperty("asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Form overriding asyncEdit due to asyncEditing client property: "+asyncEdit);
}
}
if (parentForm.getClientProperty("ios.asyncEditing") != null) {
Object async = parentForm.getClientProperty("ios.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Form overriding asyncEdit due to ios.asyncEditing client property: "+asyncEdit);
}
}
// editing - and should instead revert to legacy editing mode.
if (asyncEdit && !parentForm.isFormBottomPaddingEditingMode()) {
Container p = cmp.getParent();
// A crude estimate of how far the component needs to be able to scroll to make
// async editing viable. We start with half-way down the screen.
int keyboardClippingThresholdY = Display.getInstance().getDisplayWidth() / 2;
while (p != null) {
if (Accessor.scrollableYFlag(p) && p.getAbsoluteY() < keyboardClippingThresholdY) {
break;
}
p = p.getParent();
}
// no scrollabel parent automatically configure the text field for legacy mode
// nativeInstance.setAsyncEditMode(p != null);
asyncEdit = p != null;
// Log.p("Overriding asyncEdit due to form scrollability: "+asyncEdit);
} else if (parentForm.isFormBottomPaddingEditingMode()) {
// If form uses bottom padding mode, then we will always
// use async edit (unless the field explicitly overrides it).
asyncEdit = true;
// Log.p("Overriding asyncEdit due to form bottom padding edit mode: "+asyncEdit);
}
// then this will override all other settings.
if (cmp.getClientProperty("asyncEditing") != null) {
Object async = cmp.getClientProperty("asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field asyncEditing client property: "+asyncEdit);
}
}
if (cmp.getClientProperty("ios.asyncEditing") != null) {
Object async = cmp.getClientProperty("ios.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field ios.asyncEditing client property: "+asyncEdit);
}
}
// Finally we set the async edit mode for this field.
// System.out.println("Async edit mode is "+asyncEdit);
nativeInstance.setAsyncEditMode(asyncEdit);
textEditorHidden = false;
currentEditing = (TextArea) cmp;
// register the edited TextArea to support moving to the next field
TextEditUtil.setCurrentEditComponent(cmp);
final NativeFont fnt = f(cmp.getStyle().getFont().getNativeFont());
boolean forceSlideUpTmp = false;
final Form current = Display.getInstance().getCurrent();
if (current instanceof Dialog && !isTablet()) {
// special case, if we are editing a small dialog we want to move it
// so the bottom of the dialog shows within the screen. This is
// described in issue 505
Dialog dlg = (Dialog) current;
Component c = dlg.getDialogComponent();
if (c.getHeight() < Display.getInstance().getDisplayHeight() / 2 && c.getAbsoluteY() + c.getHeight() > Display.getInstance().getDisplayHeight() / 2) {
forceSlideUpTmp = true;
}
}
final boolean forceSlideUp = forceSlideUpTmp;
cmp.repaint();
// give the repaint one cycle to "do its magic...
final Style stl = currentEditing.getStyle();
final boolean rtl = UIManager.getInstance().getLookAndFeel().isRTL();
final Style hintStyle = currentEditing.getHintLabel() != null ? currentEditing.getHintLabel().getStyle() : stl;
if (current != null) {
Component nextComponent = current.getNextComponent(cmp);
TextEditUtil.setNextEditComponent(nextComponent);
}
Display.getInstance().callSerially(new Runnable() {
@Override
public void run() {
int x = cmp.getAbsoluteX() + cmp.getScrollX();
int y = cmp.getAbsoluteY() + cmp.getScrollY();
int w = cmp.getWidth();
int h = cmp.getHeight();
int pt = stl.getPaddingTop();
int pb = stl.getPaddingBottom();
int pl = stl.getPaddingLeft(rtl);
int pr = stl.getPaddingRight(rtl);
/*
if(currentEditing != null && currentEditing.isSingleLineTextArea()) {
switch(currentEditing.getVerticalAlignment()) {
case TextArea.CENTER:
if(h > cmp.getPreferredH()) {
y += (h / 2 - cmp.getPreferredH() / 2);
}
break;
case TextArea.BOTTOM:
if(h > cmp.getPreferredH()) {
y += (h - cmp.getPreferredH());
}
break;
}
}
*/
String hint = null;
if (currentEditing != null && currentEditing.getUIManager().isThemeConstant("nativeHintBool", true) && currentEditing.getHint() != null) {
hint = currentEditing.getHint();
}
int hintColor = hintStyle.getFgColor();
if (isAsyncEditMode()) {
// request focus triggers a scroll which flicks the textEditorHidden flag
doNotHideTextEditorSemaphore++;
try {
cmp.requestFocus();
} finally {
doNotHideTextEditorSemaphore--;
}
textEditorHidden = false;
}
boolean showToolbar = cmp.getClientProperty("iosHideToolbar") == null;
if (showToolbar && Display.getInstance().getProperty("iosHideToolbar", "false").equalsIgnoreCase("true")) {
showToolbar = false;
}
if (currentEditing != null) {
nativeInstance.editStringAt(x, y, w, h, fnt.peer, currentEditing.isSingleLineTextArea(), currentEditing.getRows(), maxSize, constraint, text, forceSlideUp, // peer,
stl.getFgColor(), // peer,
0, pt, pb, pl, pr, hint, hintColor, showToolbar, Boolean.TRUE.equals(cmp.getClientProperty("blockCopyPaste")), currentEditing.getStyle().getAlignment(), currentEditing.getVerticalAlignment());
}
}
});
if (isAsyncEditMode()) {
return;
}
editNext = false;
Display.getInstance().invokeAndBlock(new Runnable() {
@Override
public void run() {
synchronized (EDITING_LOCK) {
while (instance.currentEditing == cmp) {
try {
EDITING_LOCK.wait(20);
} catch (InterruptedException ex) {
}
}
}
}
});
if (cmp instanceof TextArea && !((TextArea) cmp).isSingleLineTextArea()) {
Form form = cmp.getComponentForm();
if (form != null) {
form.revalidate();
}
}
if (editNext) {
editNext = false;
TextEditUtil.editNextTextArea();
}
} finally {
}
}
use of com.codename1.ui.validation.Constraint 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