diff --git a/api.io/arch.xml b/api.io/arch.xml
new file mode 100644
--- /dev/null
+++ b/api.io/arch.xml
@@ -0,0 +1,1180 @@
+
+
+]>
+
+
+ The module contains APIs for creating output panes (e.g. output tabs in Output Window in the IDE)
+ and for writing data into them. It also supports some advanced techniques, e.g. color text,
+ hyperlinks, code folding, scrolling to stored positions.
+
+ SPI for providing custom implementations of output window is also included in this module, in package
+
+ Unit test will be prepared for invocable code in API classes. But most of the
+ code is just definition of API and SPI.
+
+ The design, implementation, preparing unit tests and reviews will
+ probably take several weeks.
+
+ The basic use-case is printing a simple text, e.g. text output of an application,
+ into a dedicated pane in the UI, e.g. a tab in Output Window in the IDE.
+
+ Implementations can support hyperlinks. If the hyperlink is defined by a URI,
+ it will be opened by the UI part of the application when the hyperlink is clicked
+ in the output window. The following example will open a file and place the cursor
+ at line and column specified by query part of the URI (after question mark).
+
+ Hyperlinks can be also used to invoke some code when clicked.
+
+ Print a color text. Users can select a predefined color for
+ common cases (debug, warning, failure, success), or custom
+ color specified as RGB value.
+
+ It is possible to reuse already created output pane and clear
+ all the previously printed text if it is not needed any more.
+
+ The Input/Output API and SPI is a small module
+ which contains
+ The normal implementation is
+ Backward compatibility of other modules is not broken.
+
+ This module should replace original I/O API module
+
+ Yes. There is not much to internationalize.
+
+ The module defines an API.
+
+ N/A. No settings are read or written by this module.
+
+ You will very likely also want to declare
+ to ensure that an Output Window implementation is in fact enabled.
+ Just the module JAR.
+
+ Yes.
+
+ No; only API classes are public.
+
+ Anywhere.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ Should be thread safe.
+
+ Plain Unicode text only.
+
+ N/A
+
+ None.
+
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ N/A
+
+ No.
+
+ No.
+
+ Scalability in GUI speed and memory consumption is probably limited
+ only by the Output Window implementation.
+
+ No special behavior.
+
+ No.
+
+ No.
+
+ No, but the implementation may.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+
+ No.
+ org.netbeans.spi.io
+
+ InputOutput io = InputOutput.get("UseCase1", true);
+ io.getOut().println("This is a simple output");
+ io.getOut().close();
+
+
+ InputOutput io = InputOutput.get("UseCase2", false);
+ io.getOut().print("A line containing a ");
+ io.getOut().print("hyperlink", Hyperlink.forURI(new URI("file://n:/test/Test.java?line=4&col=2")));
+ io.getOut().println(" for a URI.");
+ io.getOut().close();
+
+
+ InputOutput io = InputOutput.get("UseCase3", true);
+ io.getOut().print("A line containing a ");
+ io.getOut().print("hyperlink", Hyperlink.onClick(new Runnable() {
+ public void run() {
+ System.gc();
+ }
+ }));
+ io.getOut().println(" for invocation of custom code.");
+ io.getOut().close();
+
+
+ InputOutput io = InputOutput.get("UseCase4", true);
+ io.getOut().println("Let's print some info", OutputColor.debug());
+ io.getOut().println("or warning with appropriate color", OutputColor.warning());
+ io.getOut().println("Maybe also text with custom reddish color", OutputColor.rgb(255, 16, 16));
+ io.getOut().close();
+
+
+ InputOutput io = InputOutput.get("UseCase5", true);
+ io.getOut().println("Let's print some text");
+ io.getErr().println("and reset the pane immediately.");
+ io.reset();
+ io.getOut().println("The pane is now empty and we can reuse it simply");
+ io.getOut().close();
+
+ InputOutput
and related interfaces used in
+ driving the Output Window.
+ org.netbeans.core.output2
.
+ org.openide.io
, which has the same goals, but which is
+ not UI independent, and which is difficult to extend.
+ OpenIDE-Module-Requires: org.netbeans.api.io.IOProvider
+ IOProvider.getDefault()
asks lookup for the first instance
+ of InputOutputProvider
. This is normally provided by
+ org.netbeans.core.output2
.
+ IOProvider.getDefault().getIO("MyTab", false)
(pass true if
+ * there may be an existing tab with the same name and you want to write to a
+ * new tab).
+ *
+ * @author Jesse Glick, Jaroslav Havlin
+ */
+public abstract class IOProvider {
+
+ private IOProvider() {
+ }
+
+ /**
+ * Get the default I/O provider.
+ *
+ * Normally this is taken from {@link Lookup#getDefault} but if there is no + * instance in lookup, a fallback instance is created which just uses the + * standard system I/O streams. This is useful for unit tests and perhaps + * for standalone usage of various libraries. + *
+ * + * @return The default instance (never null). + */ + @NonNull + public static IOProvider getDefault() { + InputOutputProvider, ?> def = Lookup.getDefault().lookup(InputOutputProvider.class); + if (def != null) { + return wrapProvider(def); + } else { + return wrapProvider(new Trivial()); + } + } + + private static IOProvider wrapProvider( + InputOutputProvider provider) { + + return new Impl(provider); + } + + /** + * Gets IOProvider of selected name or delegates to getDefault() if none was + * found. + * + * @param name ID of provider. + * @return The instance corresponding to provided name or default instance + * if not found. + */ + @NonNull + public static IOProvider get(@NonNull String name) { + Parameters.notNull("name", name); + + @SuppressWarnings("rawtypes") + Collection extends InputOutputProvider> providers + = Lookup.getDefault().lookupAll(InputOutputProvider.class); + + for (InputOutputProvider, ?> p : providers) { + if (p.getName().equals(name)) { + return wrapProvider(p); + } + } + return getDefault(); + } + + /** + * Gets name (id) of provider. + * + * @return Name of this provider. + */ + @NonNull + public abstract String getName(); + + /** + * Get a named instance of InputOutput, which represents an output tab in + * the output window. Streams for reading/writing can be accessed via + * getters on the returned instance. + * + * @param name A localised display name for the tab. + * @param newIO If true, a newInputOutput
is
+ * returned, else an existing InputOutput
of the same name may
+ * be returned.
+ * @return An InputOutput
instance for accessing the new tab.
+ * @see InputOutput
+ */
+ @NonNull
+ public abstract InputOutput getIO(@NonNull String name, boolean newIO);
+
+ /**
+ * Get a named instance of InputOutput, which represents an output tab in
+ * the output window. Streams for reading/writing can be accessed via
+ * getters on the returned instance.
+ *
+ * @param name A localised display name for the tab.
+ * @param newIO If true, a new InputOutput
is
+ * returned, else an existing InputOutput
of the same name may
+ * be returned.
+ * @param lookup Lookup which may contain additional information for various
+ * implementations of output window.
+ * @return An InputOutput
instance for accessing the new tab.
+ * @see InputOutput
+ */
+ @NonNull
+ public abstract InputOutput getIO(@NonNull String name, boolean newIO,
+ @NonNull Lookup lookup);
+
+ /**
+ * Implementation of IOProvider that uses {@link InputOutputProvider} SPI
+ * internally.
+ *
+ * @param
+ * @param
+ */
+ private static class Impl extends IOProvider {
+
+ private final InputOutputProvider impl;
+
+ public Impl(InputOutputProvider impl) {
+ this.impl = impl;
+ }
+
+ @Override
+ public String getName() {
+ return impl.getName();
+ }
+
+ @Override
+ public InputOutput getIO(String name, boolean newIO) {
+ return getIO(name, newIO, Lookup.EMPTY);
+ }
+
+ @Override
+ public InputOutput getIO(String name, boolean newIO, Lookup lookup) {
+ Parameters.notNull("name", name);
+ Parameters.notNull("lookup", lookup);
+ return InputOutput.create(impl, impl.getIO(name, newIO, lookup));
+ }
+ }
+
+ /**
+ * Trivial implementation of {@link IOProvider} that uses system input,
+ * output and error streams.
+ */
+ private static class Trivial implements InputOutputProvider