public void printElementDecl()

in src/main/org/apache/tools/ant/taskdefs/AntStructure.java [250:362]


        public void printElementDecl(final PrintWriter out, final Project p,
                                     final String name, final Class<?> element) {

            if (visited.containsKey(name)) {
                return;
            }
            visited.put(name, "");

            IntrospectionHelper ih;
            try {
                ih = IntrospectionHelper.getHelper(p, element);
            } catch (final Throwable t) {
                /*
                 * TODO - failed to load the class properly.
                 *
                 * should we print a warning here?
                 */
                return;
            }

            StringBuilder sb = new StringBuilder("<!ELEMENT ").append(name).append(" ");

            if (Reference.class.equals(element)) {
                sb.append(String.format("EMPTY>%n<!ATTLIST %s%n"
                                + "          id ID #IMPLIED%n          refid IDREF #IMPLIED>%n",
                        name));
                out.println(sb);
                return;
            }

            final List<String> v = new ArrayList<>();
            if (ih.supportsCharacters()) {
                v.add("#PCDATA");
            }

            if (TaskContainer.class.isAssignableFrom(element)) {
                v.add(TASKS);
            }

            v.addAll(Collections.list(ih.getNestedElements()));

            final Collector<CharSequence, ?, String> joinAlts =
                Collectors.joining(" | ", "(", ")");

            if (v.isEmpty()) {
                sb.append("EMPTY");
            } else {
                sb.append(v.stream().collect(joinAlts));
                if (v.size() > 1 || !"#PCDATA".equals(v.get(0))) {
                    sb.append("*");
                }
            }
            sb.append(">");
            out.println(sb);

            sb = new StringBuilder();
            sb.append(String.format("<!ATTLIST %s%n          id ID #IMPLIED", name));

            for (final String attrName : Collections.list(ih.getAttributes())) {
                if ("id".equals(attrName)) {
                    continue;
                }

                sb.append(String.format("%n          %s ", attrName));
                final Class<?> type = ih.getAttributeType(attrName);
                if (type.equals(Boolean.class) || type.equals(Boolean.TYPE)) {
                    sb.append(BOOLEAN).append(" ");
                } else if (Reference.class.isAssignableFrom(type)) {
                    sb.append("IDREF ");
                } else if (EnumeratedAttribute.class.isAssignableFrom(type)) {
                    try {
                        final EnumeratedAttribute ea =
                            type.asSubclass(EnumeratedAttribute.class).getDeclaredConstructor().newInstance();
                        final String[] values = ea.getValues();
                        if (values == null || values.length == 0
                            || !areNmtokens(values)) {
                            sb.append("CDATA ");
                        } else {
                            sb.append(Stream.of(values).collect(joinAlts)).append(" ");
                        }
                    } catch (final InstantiationException | IllegalAccessException
                            | NoSuchMethodException | InvocationTargetException ie) {
                        sb.append("CDATA ");
                    }
                } else if (Enum.class.isAssignableFrom(type)) {
                    try {
                        final Enum<?>[] values =
                            (Enum<?>[]) type.getMethod("values").invoke(null);
                        if (values.length == 0) {
                            sb.append("CDATA ");
                        } else {
                            sb.append(Stream.of(values).map(Enum::name)
                                .collect(joinAlts)).append(" ");
                        }
                    } catch (final Exception x) {
                        sb.append("CDATA ");
                    }
                } else {
                    sb.append("CDATA ");
                }
                sb.append("#IMPLIED");
            }
            sb.append(String.format(">%n"));
            out.println(sb);

            for (String nestedName : v) {
                if (!"#PCDATA".equals(nestedName)
                    && !TASKS.equals(nestedName)
                    && !TYPES.equals(nestedName)) {
                    printElementDecl(out, p, nestedName, ih.getElementType(nestedName));
                }
            }
        }