Search in sources :

Example 26 with Constraint

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);
}
Also used : TextArea(com.codename1.ui.TextArea) BasicEditField(net.rim.device.api.ui.component.BasicEditField) Font(net.rim.device.api.ui.Font) Graphics(net.rim.device.api.ui.Graphics) Animation(com.codename1.ui.animations.Animation) Component(com.codename1.ui.Component) PeerComponent(com.codename1.ui.PeerComponent)

Example 27 with Constraint

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);
    }
}
Also used : ComponentAnimation(com.codename1.ui.animations.ComponentAnimation)

Example 28 with Constraint

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 {
    }
}
Also used : TextArea(com.codename1.ui.TextArea) Form(com.codename1.ui.Form) Container(com.codename1.ui.Container) Dialog(com.codename1.ui.Dialog) Style(com.codename1.ui.plaf.Style) BrowserComponent(com.codename1.ui.BrowserComponent) Component(com.codename1.ui.Component) PeerComponent(com.codename1.ui.PeerComponent)

Example 29 with Constraint

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;
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) java.util(java.util) ExecutableType(javax.lang.model.type.ExecutableType) RADDoc(com.codename1.rad.annotations.RADDoc) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) Collectors(java.util.stream.Collectors) File(java.io.File) TypeKind(javax.lang.model.type.TypeKind) RAD(com.codename1.rad.annotations.RAD) TypeMirror(javax.lang.model.type.TypeMirror) DeclaredType(javax.lang.model.type.DeclaredType) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) javax.lang.model.element(javax.lang.model.element) TypeMirror(javax.lang.model.type.TypeMirror) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) FileOutputStream(java.io.FileOutputStream) File(java.io.File) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

Component (com.codename1.ui.Component)7 TextArea (com.codename1.ui.TextArea)7 Container (com.codename1.ui.Container)5 Style (com.codename1.ui.plaf.Style)5 PeerComponent (com.codename1.ui.PeerComponent)3 BorderLayout (com.codename1.ui.layouts.BorderLayout)3 Inset (com.codename1.ui.layouts.LayeredLayout.LayeredLayoutConstraint.Inset)3 Point (java.awt.Point)3 java.util (java.util)3 Button (com.codename1.ui.Button)2 Form (com.codename1.ui.Form)2 Label (com.codename1.ui.Label)2 TextField (com.codename1.ui.TextField)2 ComponentAnimation (com.codename1.ui.animations.ComponentAnimation)2 Dimension (com.codename1.ui.geom.Dimension)2 BoxLayout (com.codename1.ui.layouts.BoxLayout)2 UITimer (com.codename1.ui.util.UITimer)2 java.awt (java.awt)2 AttributedString (java.text.AttributedString)2 Timer (java.util.Timer)2