diff --git a/core.output2/manifest.mf b/core.output2/manifest.mf --- a/core.output2/manifest.mf +++ b/core.output2/manifest.mf @@ -4,5 +4,5 @@ OpenIDE-Module-Localizing-Bundle: org/netbeans/core/output2/Bundle.properties OpenIDE-Module-Provides: org.openide.windows.IOProvider AutoUpdate-Essential-Module: true -OpenIDE-Module-Specification-Version: 1.37 +OpenIDE-Module-Specification-Version: 1.38 diff --git a/core.output2/nbproject/project.xml b/core.output2/nbproject/project.xml --- a/core.output2/nbproject/project.xml +++ b/core.output2/nbproject/project.xml @@ -111,7 +111,16 @@ - 1.40 + 1.45 + + + + org.openide.io.base + + + + 1 + 1.0 diff --git a/core.output2/src/org/netbeans/core/output2/NbIO.java b/core.output2/src/org/netbeans/core/output2/NbIO.java --- a/core.output2/src/org/netbeans/core/output2/NbIO.java +++ b/core.output2/src/org/netbeans/core/output2/NbIO.java @@ -54,6 +54,8 @@ import java.io.IOException; import java.io.Reader; import org.netbeans.core.output2.options.OutputOptions; +import org.openide.io.base.ExtendableWriter; +import org.openide.io.base.InputOutputBase; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; @@ -72,7 +74,7 @@ * * @author Tim Boudreau */ -class NbIO implements InputOutput, Lookup.Provider { +class NbIO implements InputOutput, InputOutputBase, Lookup.Provider { private Boolean focusTaken = null; private volatile boolean closed = false; @@ -248,6 +250,7 @@ return actions; } + @Override public void reset() { if (Controller.LOG) Controller.log (this + ": reset"); closed = false; @@ -317,6 +320,16 @@ return lookup; } + @Override + public ExtendableWriter getExtendableOut() { + return (NbWriter) getOut(); + } + + @Override + public ExtendableWriter getExtandableErr() { + return (NbWriter) getErr(); + } + class IOReader extends Reader { private boolean pristine = true; IOReader() { diff --git a/core.output2/src/org/netbeans/core/output2/NbIOProvider.java b/core.output2/src/org/netbeans/core/output2/NbIOProvider.java --- a/core.output2/src/org/netbeans/core/output2/NbIOProvider.java +++ b/core.output2/src/org/netbeans/core/output2/NbIOProvider.java @@ -45,7 +45,6 @@ package org.netbeans.core.output2; import java.io.IOException; -import java.util.WeakHashMap; import javax.swing.Action; import org.openide.util.Exceptions; import org.openide.util.NbBundle; @@ -55,19 +54,23 @@ import org.openide.windows.OutputWriter; /** - * Supplies Output Window implementation through Lookup. + * Supplies Output Window implementation through Lookup. Provider of I/O + * instances for the org.openide.io (package org.openide.windows) API. + * * @author Jesse Glick, Tim Boudreau */ @org.openide.util.lookup.ServiceProvider(service=org.openide.windows.IOProvider.class, position=100) public final class NbIOProvider extends IOProvider { - private static final WeakHashMap containerPairMaps = - new WeakHashMap(); private static final String STDOUT = NbBundle.getMessage(NbIOProvider.class, "LBL_STDOUT"); //NOI18N - private static final String NAME = "output2"; // NOI18N - + @Override + public String getName() { + return SharedProvider.getInstance().getName(); + } + + @Override public OutputWriter getStdOut() { if (Controller.LOG) { Controller.log("NbIOProvider.getStdOut"); @@ -93,6 +96,7 @@ } + @Override public InputOutput getIO(String name, boolean newIO) { return getIO (name, newIO, new Action[0], null); } @@ -108,53 +112,15 @@ } @Override - public String getName() { - return NAME; + public InputOutput getIO(String name, boolean newIO, Action[] actions, + IOContainer ioContainer) { + + return SharedProvider.getInstance().getIO(name, newIO, actions, + ioContainer); } - @Override - public InputOutput getIO(String name, boolean newIO, - Action[] toolbarActions, IOContainer ioContainer) { - if (Controller.LOG) { - Controller.log("GETIO: " + name + " new:" + newIO); - } - IOContainer realIoContainer = ioContainer == null - ? IOContainer.getDefault() : ioContainer; - NbIO result; - synchronized (containerPairMaps) { - PairMap namesToIos = containerPairMaps.get(realIoContainer); - result = namesToIos != null ? namesToIos.get(name) : null; - } - if (result == null || newIO) { - result = new NbIO(name, toolbarActions, realIoContainer); - synchronized (containerPairMaps) { - PairMap namesToIos = containerPairMaps.get(realIoContainer); - if (namesToIos == null) { - namesToIos = new PairMap(); - containerPairMaps.put(realIoContainer, namesToIos); - } - namesToIos.add(name, result); - } - NbIO.post(new IOEvent(result, IOEvent.CMD_CREATE, newIO)); - } - return result; - } - - - static void dispose (NbIO io) { - IOContainer ioContainer = io.getIOContainer(); - if (ioContainer == null) { - ioContainer = IOContainer.getDefault(); - } - synchronized (containerPairMaps) { - PairMap namesToIos = containerPairMaps.get(ioContainer); - if (namesToIos != null) { - namesToIos.remove(io); - if (namesToIos.isEmpty()) { - containerPairMaps.remove(ioContainer); - } - } - } + static void dispose(NbIO io) { + SharedProvider.dispose(io); } } diff --git a/core.output2/src/org/netbeans/core/output2/NbIOProviderBase.java b/core.output2/src/org/netbeans/core/output2/NbIOProviderBase.java new file mode 100644 --- /dev/null +++ b/core.output2/src/org/netbeans/core/output2/NbIOProviderBase.java @@ -0,0 +1,67 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.netbeans.core.output2; + +import javax.swing.Action; +import org.openide.io.base.IOProviderBase; +import org.openide.io.base.InputOutputBase; +import org.openide.util.lookup.ServiceProvider; + +/** + * Provider of I/O instances for the org.openide.io.base API. + * + * @author jhavlin + */ +@ServiceProvider(service = IOProviderBase.class, position = 100) +public class NbIOProviderBase extends IOProviderBase { + + @Override + public String getName() { + return SharedProvider.getInstance().getName(); + } + + @Override + public InputOutputBase getIO(String name, boolean newIO) { + return SharedProvider.getInstance().getIO(name, newIO, new Action[0], + null); + } +} diff --git a/core.output2/src/org/netbeans/core/output2/NbWriter.java b/core.output2/src/org/netbeans/core/output2/NbWriter.java --- a/core.output2/src/org/netbeans/core/output2/NbWriter.java +++ b/core.output2/src/org/netbeans/core/output2/NbWriter.java @@ -47,7 +47,16 @@ import org.openide.windows.OutputWriter; import org.openide.windows.OutputListener; import java.io.IOException; +import java.util.Collections; +import java.util.Set; +import org.openide.io.base.ExtendableWriter; +import org.openide.io.base.InputOutputBase; +import org.openide.io.base.OutputEventBase; +import org.openide.io.base.OutputListenerBase; import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.windows.InputOutput; +import org.openide.windows.OutputEvent; /** @@ -57,7 +66,7 @@ * which it replaces when reset() is called; an OutputDocument is implemented directly over an * OutWriter, so the immutable OutWriter lasts until the OutputDocument is destroyed. */ -class NbWriter extends OutputWriter { +class NbWriter extends OutputWriter implements ExtendableWriter { private final NbIO owner; /** * Make an output writer. @@ -165,4 +174,58 @@ ((OutWriter) out).println(s); } } + + @Override + public Set> getExtendingTypes() { + return Collections.>singleton(OutputListenerBase.class); + } + + @Override + public void println(String s, Lookup extendingInfo) throws IOException { + println(s, extendingInfo, false); + } + + @Override + public void println(String s, Lookup extendingInfo, boolean important) + throws IOException { + OutputListenerBase olb = extendingInfo.lookup(OutputListenerBase.class); + if (olb != null) { + OutputListener ol = convertToOutputListener(olb); + println(s, ol, important); + } else { + println(s); + } + } + + private OutputListener convertToOutputListener(final OutputListenerBase l) { + return new OutputListener() { + + @Override + public void outputLineSelected(OutputEvent ev) { + l.outputLineSelected(convertToOutputEventBase(ev)); + } + + @Override + public void outputLineAction(OutputEvent ev) { + l.outputLineAction(convertToOutputEventBase(ev)); + } + + @Override + public void outputLineCleared(OutputEvent ev) { + l.outputLineCleared(convertToOutputEventBase(ev)); + } + }; + } + + private OutputEventBase convertToOutputEventBase(final OutputEvent e) { + InputOutput origIO = e.getInputOutput(); + InputOutputBase src = origIO instanceof InputOutputBase + ? (InputOutputBase) origIO : owner; + return new OutputEventBase(src) { + @Override + public String getLine() { + return e.getLine(); + } + }; + } } diff --git a/core.output2/src/org/netbeans/core/output2/SharedProvider.java b/core.output2/src/org/netbeans/core/output2/SharedProvider.java new file mode 100644 --- /dev/null +++ b/core.output2/src/org/netbeans/core/output2/SharedProvider.java @@ -0,0 +1,119 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.netbeans.core.output2; + +import java.util.WeakHashMap; +import javax.swing.Action; +import org.openide.windows.IOContainer; + +/** + * Shared provider for both the original (org.openide.io/org.openide.windows) + * and the base (org.openide.io.base) APIs. + * + * @author jhavlin + */ +public class SharedProvider { + + private static final WeakHashMap containerPairMaps + = new WeakHashMap(); + private static final String NAME = "output2"; // NOI18N + + private static class SingletonHolder { + + static SharedProvider INSTANCE = new SharedProvider(); + } + + public static SharedProvider getInstance() { + return SingletonHolder.INSTANCE; + } + + private SharedProvider() { + System.out.println("x"); + } + + public String getName() { + return NAME; + } + + NbIO getIO(String name, boolean newIO, + Action[] toolbarActions, IOContainer ioContainer) { + if (Controller.LOG) { + Controller.log("GETIO: " + name + " new:" + newIO); + } + IOContainer realIoContainer = ioContainer == null + ? IOContainer.getDefault() : ioContainer; + NbIO result; + synchronized (containerPairMaps) { + PairMap namesToIos = containerPairMaps.get(realIoContainer); + result = namesToIos != null ? namesToIos.get(name) : null; + } + if (result == null || newIO) { + result = new NbIO(name, toolbarActions, realIoContainer); + synchronized (containerPairMaps) { + PairMap namesToIos = containerPairMaps.get(realIoContainer); + if (namesToIos == null) { + namesToIos = new PairMap(); + containerPairMaps.put(realIoContainer, namesToIos); + } + namesToIos.add(name, result); + } + NbIO.post(new IOEvent(result, IOEvent.CMD_CREATE, newIO)); + } + return result; + } + + static void dispose(NbIO io) { + IOContainer ioContainer = io.getIOContainer(); + if (ioContainer == null) { + ioContainer = IOContainer.getDefault(); + } + synchronized (containerPairMaps) { + PairMap namesToIos = containerPairMaps.get(ioContainer); + if (namesToIos != null) { + namesToIos.remove(io); + if (namesToIos.isEmpty()) { + containerPairMaps.remove(ioContainer); + } + } + } + } +} diff --git a/nbbuild/build.properties b/nbbuild/build.properties --- a/nbbuild/build.properties +++ b/nbbuild/build.properties @@ -176,6 +176,7 @@ core.netigso,\ o.n.swing.outline,\ o.n.swing.tabcontrol,\ + openide.io.base,\ editor.indent,\ editor.bracesmatching,\ j2ee.metadata,\ diff --git a/nbbuild/cluster.properties b/nbbuild/cluster.properties --- a/nbbuild/cluster.properties +++ b/nbbuild/cluster.properties @@ -250,6 +250,7 @@ openide.filesystems.compat8,\ openide.filesystems.nb,\ openide.io,\ + openide.io.base,\ openide.loaders,\ openide.nodes,\ openide.options,\ diff --git a/openide.io.base/apichanges.xml b/openide.io.base/apichanges.xml new file mode 100644 --- /dev/null +++ b/openide.io.base/apichanges.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + Base I/O APIs + + + + + + + + + + + + + + + + + Change History for the Base I/O APIs + + + + + + +

Introduction

+ +

This document lists changes made to the Base I/O APIs.

+ + +
+ + +

@FOOTER@

+ + +
+ +
+ diff --git a/openide.io.base/arch.xml b/openide.io.base/arch.xml new file mode 100644 --- /dev/null +++ b/openide.io.base/arch.xml @@ -0,0 +1,1115 @@ + + +]> + + + + &api-questions; + + + + + +

+ Just a base API/SPI for defining the output window. +

+
+
+ + + + + +

+ Too little code to test. +

+
+ + + + + +

+ Done. +

+
+ + + + + +

There is an SPI but additional implementations are not expected. The API is most important.

+

+ Simple usage example: +

+
+  InputOutput io = IOProviderBase.getDefault().getIO("My Window", true);
+  io.select();
+  OutputWriter w = io.getOut();
+  w.println("Line of plain text.");
+  OutputListenerBase listener = new OutputListenerBase() {
+      public void outputLineAction(OutputEventBase ev) {
+          StatusDisplayer.getDefault().setStatusText("Hyperlink clicked!");
+      }
+      public void outputLineSelected(OutputEventBase ev) {
+          // Let's not do anything special.
+      }
+      public void outputLineCleared(OutputEventBase ev) {
+          // Leave it blank, no state to remove.
+      }
+  };
+  InstanceContent ic = new InstanceContent();
+  if (ow.getExtendingTypes().contains(OutputListenerBase.class)) {
+    ic.add(istener);
+  }
+  w.println("Line of hyperlinked text.", new AbstractLookup(ic), true);
+  
+
+ + + + + +

+ The Base Input/Output APIs is a small API module + which contains InputOutputBase and related interfaces used in + driving the Output Window. The normal implementation is + org.netbeans.core.output2. +

+

+ The API was extracted from module openide.io, which depends on some + GUI-related classes. This module has no such dependencies. +

+
+ + + + + + + + + + + + +

+ This module is an alternative for org.openide.io, it has similar goals, but + less dependencies. +

+
+ + + + + +

+ Yes. +

+
+ + + + + +

+ The module defines an API. +

+
+ + + + + +

+ N/A +

+
+ + + + + +

+ 1.7 +

+
+ + + + + +

+ JRE +

+
+ + + + + + + + + + + + +

+ None. +

+
+ + + + + +

+ Any +

+
+ + + + + +

+ You will very likely also want to declare +

+
OpenIDE-Module-Requires: org.openide.io.base.IOProviderBase
+

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 +

+
+ + + + + + IOProviderBase.getDefault() asks lookup for the first instance + of itself. This is normally provided by org.netbeans.core.output2. + + + + + + +

+ 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 +

+
+ +
diff --git a/openide.io.base/build.xml b/openide.io.base/build.xml new file mode 100644 --- /dev/null +++ b/openide.io.base/build.xml @@ -0,0 +1,5 @@ + + + Builds, tests, and runs the project org.openide.io.base + + diff --git a/openide.io.base/manifest.mf b/openide.io.base/manifest.mf new file mode 100644 --- /dev/null +++ b/openide.io.base/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.openide.io.base/1 +OpenIDE-Module-Localizing-Bundle: org/openide/io/base/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + diff --git a/openide.io.base/nbproject/project.properties b/openide.io.base/nbproject/project.properties new file mode 100644 --- /dev/null +++ b/openide.io.base/nbproject/project.properties @@ -0,0 +1,4 @@ +is.autoload=true +javac.source=1.6 +javac.compilerargs=-Xlint -Xlint:-serial +javadoc.arch=${basedir}/arch.xml diff --git a/openide.io.base/nbproject/project.xml b/openide.io.base/nbproject/project.xml new file mode 100644 --- /dev/null +++ b/openide.io.base/nbproject/project.xml @@ -0,0 +1,30 @@ + + + org.netbeans.modules.apisupport.project + + + org.openide.io.base + + + org.openide.util.base + + + + 9.1 + + + + org.openide.util.lookup + + + + 8.25 + + + + + org.openide.io.base + + + + diff --git a/openide.io.base/src/org/openide/io/base/Bundle.properties b/openide.io.base/src/org/openide/io/base/Bundle.properties new file mode 100644 --- /dev/null +++ b/openide.io.base/src/org/openide/io/base/Bundle.properties @@ -0,0 +1,1 @@ +OpenIDE-Module-Name=Base I/O APIs diff --git a/openide.io.base/src/org/openide/io/base/ExtendableWriter.java b/openide.io.base/src/org/openide/io/base/ExtendableWriter.java new file mode 100644 --- /dev/null +++ b/openide.io.base/src/org/openide/io/base/ExtendableWriter.java @@ -0,0 +1,95 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.openide.io.base; + +import java.io.IOException; +import java.util.Set; +import org.openide.util.Lookup; + +/** + * Complementary API to {@link @PrintWriter} for support of printing lines + * extended by listeners or tags. + * + * @author jhavlin + */ +public interface ExtendableWriter { + + /** + * Set of classes or interfaces that are supported by this implementation of + * OutputWriterBase and which can be put to the lookup passed to + * {@link #println(String, Lookup)} or + * {@link #println(String, Lookup, boolean)}. + * + * @return Set of supported classes and interfaces. Can be empty, never + * null. + */ + Set> getExtendingTypes(); + + /** + * Print a line which will be displayed as a hyperlink, calling the action + * specifided in the {@link Lookup} object if it is clicked, if the caret + * enters it, or if the enter key is pressed over it. + * + * @param s a string to print to the tab + * @param extendingInfo lookup containing extending info for the text, e.g. + * an output listener and/or an output tag. + * @throws IOException if the string could not be printed + */ + void println(String s, Lookup extendingInfo) throws + IOException; + + /** + * Print a line which will be displayed as a hyperlink, calling the action + * specifided in the {@link Lookup} object if it is clicked, if the caret + * enters it, or if the enter key is pressed over it. + * + * @param s a string to print to the tab + * @param extendingInfo lookup containing extending info for the text, e.g. + * an output listener and/or an output tag. + * @param important mark the line as important. Makes the UI respond + * appropriately, eg. stop the automatic scrolling or highlight the + * hyperlink. + * @throws IOException if the string could not be printed + */ + void println(String s, Lookup extendingInfo, + boolean important) throws IOException; +} diff --git a/openide.io.base/src/org/openide/io/base/IOProviderBase.java b/openide.io.base/src/org/openide/io/base/IOProviderBase.java new file mode 100644 --- /dev/null +++ b/openide.io.base/src/org/openide/io/base/IOProviderBase.java @@ -0,0 +1,342 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.openide.io.base; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.StringWriter; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; +import org.openide.util.Lookup; + +/** + * A factory for IO tabs. To create a new tab to write to, call e.g. + * 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 jhavlin + */ +public abstract class IOProviderBase { + + public static IOProviderBase getDefault() { + IOProviderBase iopb = Lookup.getDefault().lookup(IOProviderBase.class); + if (iopb == null) { + iopb = new Trivial(); + } + return iopb; + } + + /** + * Gets IOProviderBase 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 + */ + public static IOProviderBase get(String name) { + Collection res = Lookup.getDefault().lookupAll( + IOProviderBase.class); + for (IOProviderBase iop : res) { + if (iop.getName().equals(name)) { + return iop; + } + } + return getDefault(); + } + + /** + * Gets name (ID) of provider + * + * @return name of provider + */ + 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 new InputOutput is + * returned, else an existing InputOutput of the same name may + * be returned + * @return an InputOutput instance for accessing the new tab + * @see InputOutputBase + */ + public abstract InputOutputBase getIO(String name, boolean newIO); + + /** + * Fallback implementation. + */ + private static final class Trivial extends IOProviderBase { + + private static final Reader in = new BufferedReader( + new InputStreamReader(System.in)); + private static final PrintStream out = System.out; + private static final PrintStream err = System.err; + + public Trivial() { + } + + @Override + public String getName() { + return "Trivial"; //NOI18N + } + + @Override + public InputOutputBase getIO(String name, boolean newIO) { + return new TrivialIO(name); + } + + @SuppressWarnings("deprecation") + private final class TrivialIO implements InputOutputBase { + + private final String name; + + public TrivialIO(String name) { + this.name = name; + } + + @Override + public Reader getIn() { + return in; + } + + @Override + public PrintWriter getOut() { + return new TrivialOW(out, name); + } + + @Override + public PrintWriter getErr() { + return new TrivialOW(err, name); + } + + public Reader flushReader() { + return getIn(); + } + + @Override + public boolean isClosed() { + return false; + } + + @Override + public void closeInputOutput() { + } + + @Override + public void select() { + } + + @Override + public void reset() { + } + + @Override + public ExtendableWriter getExtendableOut() { + return new TrivialExtendableWriter(getOut()); + } + + @Override + public ExtendableWriter getExtandableErr() { + return new TrivialExtendableWriter(getErr()); + } + + @Override + public Lookup getLookup() { + return Lookup.EMPTY; + } + } + + private static final class TrivialOW extends PrintWriter { + + private static int count = 0; + private final String name; + private final PrintStream stream; + + @SuppressWarnings("ValueOfIncrementOrDecrementUsed") + public TrivialOW(PrintStream stream, String name) { + // XXX using super(new PrintWriter(stream)) does not seem to work for some reason! + super(new StringWriter()); + this.stream = stream; + if (name != null) { + this.name = name; + } else { + this.name = "anon-" + ++count; // NOI18N + } + } + + private void prefix(boolean hyperlink) { + if (hyperlink) { + stream.print("[" + name + "]* "); // NOI18N + } else { + stream.print("[" + name + "] "); // NOI18N + } + } + + @Override + public void println(float x) { + prefix(false); + stream.println(x); + } + + @Override + public void println(double x) { + prefix(false); + stream.println(x); + } + + @Override + public void println() { + prefix(false); + stream.println(); + } + + @Override + public void println(Object x) { + prefix(false); + stream.println(x); + } + + @Override + public void println(int x) { + prefix(false); + stream.println(x); + } + + @Override + public void println(char x) { + prefix(false); + stream.println(x); + } + + @Override + public void println(long x) { + prefix(false); + stream.println(x); + } + + @Override + @SuppressWarnings("ImplicitArrayToString") + public void println(char[] x) { + prefix(false); + stream.println(x); + } + + @Override + public void println(boolean x) { + prefix(false); + stream.println(x); + } + + @Override + public void println(String x) { + prefix(false); + stream.println(x); + } + + @Override + public void write(int c) { + stream.write(c); + } + + @Override + public void write(char[] buf, int off, int len) { + String s = new String(buf, off, len); + if (s.endsWith("\n")) { + println(s.substring(0, s.length() - 1)); + } else { + try { + stream.write(s.getBytes()); + } catch (IOException x) { + } + } + } + + @Override + public void write(String s, int off, int len) { + String sub = s.substring(off, off + len); + if (sub.endsWith("\n")) { + println(sub.substring(0, sub.length() - 1)); + } else { + try { + stream.write(sub.getBytes()); + } catch (IOException x) { + } + } + } + } + + public static class TrivialExtendableWriter implements ExtendableWriter { + private final PrintWriter printWriter; + + public TrivialExtendableWriter(PrintWriter printWriter) { + this.printWriter = printWriter; + } + + @Override + public Set> getExtendingTypes() { + return Collections.emptySet(); + } + + @Override + public void println(String s, Lookup extendingInfo) throws + IOException { + printWriter.println(s); + } + + @Override + public void println(String s, Lookup extendingInfo, + boolean important) throws IOException { + printWriter.println(s); + } + } + } +} diff --git a/openide.io.base/src/org/openide/io/base/InputOutputBase.java b/openide.io.base/src/org/openide/io/base/InputOutputBase.java new file mode 100644 --- /dev/null +++ b/openide.io.base/src/org/openide/io/base/InputOutputBase.java @@ -0,0 +1,134 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.openide.io.base; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Reader; +import org.openide.util.Lookup; + +/** + * An I/O connection to one tab on the Output Window. To acquire an instance to + * write to, call, e.g., + * IOProviderBase.getDefault().getIO("someName", false). To get + * actual streams to write to, call getOut() or + * getErr() on the returned instance. + *

+ * Generally it is preferable not to hold a reference to an instance of + * {@link org.openide.io.base.InputOutputBase}, but rather to fetch it by name + * from {@link org.openide.io.base.IOProviderBase} as needed. + *

+ * + * @see ExtendableWriter + * @author Ian Formanek, Jaroslav Tulach, Petr Hamernik, Ales Novak, Jan + * Jancura, Jaroslav Havlin + */ +public interface InputOutputBase extends Lookup.Provider { + + /** + * Acquire an output writer to write to the tab. This is the usual use of a + * tab--it writes to the main output pane. + * + * @return the writer + */ + public PrintWriter getOut(); + + /** + * Get a reader to read from the tab. If a reader is ever requested, an + * input line is added to the tab and used to read one line at a time. + * + * @return the reader + */ + public Reader getIn(); + + /** + * Get an output writer to write to the tab in error mode. This might show + * up in a different color than the regular output, e.g., or appear in a + * separate pane. + * + * @return the writer + */ + public PrintWriter getErr(); + + /** + * Get extension for standard output that can be used for printing lines + * with output listeners or tags. + * + * @return Writer as an + */ + public ExtendableWriter getExtendableOut(); + + /** + * Get extension for error output that can be used for printing lines with + * output listeners or tags. + * + * @return Writer as an + */ + public ExtendableWriter getExtandableErr(); + + /** + * Closes this tab. The effect of calling any method on an instance of + * InputOutput after calling closeInputOutput() on it is + * undefined. + */ + public void closeInputOutput(); + + /** + * Test whether this tab has been closed, either by a call to + * closeInputOutput() or by the user closing the tab in the UI. + * + * @see #closeInputOutput + * @return true if it is closed + */ + public boolean isClosed(); + + /** + * Ensure this pane is visible. + */ + public void select(); + + /** + * Clean the output area. + * @throws java.io.IOException + */ + void reset() throws IOException; +} diff --git a/openide.io.base/src/org/openide/io/base/OutputEventBase.java b/openide.io.base/src/org/openide/io/base/OutputEventBase.java new file mode 100644 --- /dev/null +++ b/openide.io.base/src/org/openide/io/base/OutputEventBase.java @@ -0,0 +1,70 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.openide.io.base; + +/** + * Event fired when something happens to a line in the Output Window. + * + * @author Jaroslav Tulach, Petr Hamernik, Jaroslav Havlin + */ +public abstract class OutputEventBase extends java.util.EventObject { + /** generated Serialized Version UID */ + static final long serialVersionUID = 4809584286971828815L; + /** Create an event. + * @param src the tab in question + */ + public OutputEventBase (InputOutputBase src) { + super (src); + } + + /** Get the text on the line. + * @return the text + */ + public abstract String getLine (); + + /** Get the Output Window tab in question. + * @return the tab + */ + public InputOutputBase getInputOutput() { + return (InputOutputBase) getSource(); + } +} diff --git a/openide.io.base/src/org/openide/io/base/OutputListenerBase.java b/openide.io.base/src/org/openide/io/base/OutputListenerBase.java new file mode 100644 --- /dev/null +++ b/openide.io.base/src/org/openide/io/base/OutputListenerBase.java @@ -0,0 +1,72 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.openide.io.base; + +/** + * Listener to actions taken on a line in the Output Window. + * + * @author Jaroslav Tulach + * @version 0.11 Dec 01, 1997 + */ +public interface OutputListenerBase extends java.util.EventListener { + + /** + * Called when a line is selected. + * + * @param ev the event describing the line + */ + void outputLineSelected(OutputEventBase ev); + + /** + * Called when some sort of action is performed on a line. + * + * @param ev the event describing the line + */ + void outputLineAction(OutputEventBase ev); + + /** + * Called when a line is cleared from the buffer of known lines. + * + * @param ev the event describing the line + */ + void outputLineCleared(OutputEventBase ev); +} diff --git a/openide.io.base/src/org/openide/io/base/OutputTagBase.java b/openide.io.base/src/org/openide/io/base/OutputTagBase.java new file mode 100644 --- /dev/null +++ b/openide.io.base/src/org/openide/io/base/OutputTagBase.java @@ -0,0 +1,76 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.openide.io.base; + +import java.util.Set; + +/** + * Base class for adding tagging information to output text. + * + * @author jhavlin + */ +public interface OutputTagBase { + + /** + * Get type of this tag. + * + * @return Type of the tag. + */ + String getType(); + + /** + * Get value of an attribute specified by name. + * + * @param attributeName Name of the attribute. + * @return Value of the attribute, or null if it is not available. + * @throws IllegalArgumentException If tag of this type should not be + * queried for attribute of name {@code attributeName}. + */ + Object getAttribute(String attributeName); + + /** + * Get set of names of available attributes. + * + * @return Set of attribute names. + */ + Set getAttributeNames(); +}