org.netbeans.api.io.IOProvider Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.api.io;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Set;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.spi.io.InputOutputProvider;
import org.openide.util.Lookup;
import org.openide.util.Parameters;
/**
* A factory for IO tabs shown in the output window. 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).
*
*
* Methods of this class can be called in any thread.
*
*
* @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 {
def = getBridgingDefault();
if (def != null) {
return wrapProvider(def);
} else {
return wrapProvider(new Trivial());
}
}
}
private static IOProvider wrapProvider(
InputOutputProvider provider) {
return new Impl(provider);
}
/**
* Get default provider implementing openide.io SPI and bridge it to api.io
* SPI.
*/
private static InputOutputProvider,?,?,?> getBridgingDefault() {
return getBridging("getDefault", //NOI18N
new Class>[0], new Object[0]);
}
/**
* Get provider implementing openide.io SPI and bridge it to api.io SPI.
*
* @param name Name of the provider.
*/
private static InputOutputProvider,?,?,?> getBridging(String name) {
return getBridging("get", //NOI18N
new Class>[]{String.class},
new Object[]{name});
}
/**
* Invoke method on getter of providers implementing openide.io SPI bridged
* to api.io SPI.
*
* @param methodName Method to invoke on the getter.
* @param paramTypes Parameters types of the method.
* @param params Arguments to pass to the method.
*
* @return IOProvider bridged to InputOutputProvider returned from specified
* getter's method, or null if not available or some problem occured.
*/
private static InputOutputProvider,?,?,?> getBridging(String methodName,
Class>[] paramTypes, Object[] params) {
String className = "org.openide.io.BridgingGetter"; //NOI18N
ClassLoader cl = Lookup.getDefault().lookup(ClassLoader.class);
if (cl != null) {
try {
Class extends Object> c = Class.forName(className, true, cl);
Object instance = c.newInstance();
Method m = c.getDeclaredMethod(methodName, paramTypes);
Object result = m.invoke(instance, params);
if (result instanceof InputOutputProvider) {
return (InputOutputProvider) result;
}
} catch (ClassNotFoundException ex) {
} catch (NoSuchMethodException ex) {
} catch (SecurityException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
}
}
return null;
}
/**
* Gets IOProvider of selected name or delegates to getDefault() if none was
* found.
*
* @param id ID of provider.
* @return The instance corresponding to provided name or default instance
* if not found.
*/
@NonNull
public static IOProvider get(@NonNull String id) {
Parameters.notNull("id", id);
@SuppressWarnings("rawtypes")
Collection extends InputOutputProvider> providers
= Lookup.getDefault().lookupAll(InputOutputProvider.class);
for (InputOutputProvider, ?, ?, ?> p : providers) {
if (p.getId().equals(id)) {
return wrapProvider(p);
}
}
InputOutputProvider,?,?,?> bridgingImpl = getBridging(id);
if (bridgingImpl != null) {
return wrapProvider(bridgingImpl);
} else {
return getDefault();
}
}
/**
* Gets identifier of this provider.
*
* @return Name of this provider.
*/
@NonNull
public abstract String getId();
/**
* 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 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
* @param
*/
private static class Impl
extends IOProvider {
private final InputOutputProvider impl;
public Impl(InputOutputProvider impl) {
this.impl = impl;
}
@Override
public String getId() {
return impl.getId();
}
@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