| /* |
| * 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.openide.io; |
| |
| import java.awt.Color; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.util.ArrayDeque; |
| import java.util.Deque; |
| import java.util.EnumSet; |
| import java.util.Set; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.swing.Action; |
| import org.netbeans.api.io.Hyperlink; |
| import org.netbeans.api.io.OutputColor; |
| import org.netbeans.api.io.ShowOperation; |
| import org.netbeans.spi.io.support.Hyperlinks; |
| import org.netbeans.spi.io.InputOutputProvider; |
| import org.netbeans.spi.io.support.OutputColorType; |
| import org.netbeans.spi.io.support.OutputColors; |
| import org.openide.util.Lookup; |
| import org.openide.windows.FoldHandle; |
| import org.openide.windows.IOColorLines; |
| import org.openide.windows.IOColorPrint; |
| import org.openide.windows.IOColors; |
| import org.openide.windows.IOColors.OutputType; |
| import org.openide.windows.IOContainer; |
| import org.openide.windows.IOFolding; |
| import org.openide.windows.IOPosition; |
| import org.openide.windows.IOPosition.Position; |
| import org.openide.windows.IOProvider; |
| import org.openide.windows.IOSelect; |
| import org.openide.windows.IOTab; |
| import org.openide.windows.InputOutput; |
| import org.openide.windows.OutputEvent; |
| import org.openide.windows.OutputListener; |
| import org.openide.windows.OutputWriter; |
| |
| /** |
| * Wrapper class for converting implementations of IOProvider SPI to new SPI |
| * interface {@link InputOutputProvider}. |
| * |
| * @author jhavlin |
| */ |
| public final class BridgingInputOutputProvider |
| implements InputOutputProvider<InputOutput, OutputWriter, Position, FoldHandle> { |
| |
| private final IOProvider delegate; |
| |
| public BridgingInputOutputProvider(IOProvider delegate) { |
| this.delegate = delegate; |
| } |
| |
| private static final Logger LOG |
| = Logger.getLogger(BridgingInputOutputProvider.class.getName()); |
| |
| private final Deque<FoldHandle> foldStack = new ArrayDeque<FoldHandle>(); |
| |
| @Override |
| public String getId() { |
| return delegate.getName(); |
| } |
| |
| @Override |
| public InputOutput getIO(String name, boolean newIO, Lookup lookup) { |
| Action[] actions = lookup.lookup(Action[].class); |
| IOContainer container = lookup.lookup(IOContainer.class); |
| if (container == null && actions == null) { |
| return delegate.getIO(name, newIO); |
| } else if (newIO) { |
| if (container != null && actions != null) { |
| return delegate.getIO(name, actions, container); |
| } else if (actions != null) { |
| return delegate.getIO(name, actions); |
| } else { |
| return delegate.getIO(name, new Action[0], container); |
| } |
| } else { |
| return delegate.getIO(name, newIO, actions == null ? new Action[0] : actions, |
| container); |
| } |
| } |
| |
| @Override |
| public Reader getIn(InputOutput io) { |
| return io.getIn(); |
| } |
| |
| @Override |
| public OutputWriter getOut(InputOutput io) { |
| return io.getOut(); |
| } |
| |
| @Override |
| public OutputWriter getErr(InputOutput io) { |
| return io.getErr(); |
| } |
| |
| @Override |
| public void print(InputOutput io, OutputWriter writer, String text, |
| Hyperlink link, OutputColor outputColor, boolean printLineEnd) { |
| |
| Color awtColor = outputColorToAwtColor(io, outputColor); |
| OutputListener listener = hyperlinkToOutputListener(link); |
| boolean listenerImportant = link != null && Hyperlinks.isImportant(link); |
| try { |
| if (printLineEnd && outputColor == null) { |
| writer.println(text, listener, listenerImportant); |
| } else if (printLineEnd && IOColorLines.isSupported(io)) { |
| IOColorLines.println(io, text, listener, listenerImportant, |
| awtColor); |
| } else if (IOColorPrint.isSupported(io)) { |
| IOColorPrint.print(io, text, listener, listenerImportant, |
| awtColor); |
| if (printLineEnd) { |
| writer.println(); |
| } |
| } else if (printLineEnd) { |
| writer.println(text); |
| } else { |
| writer.print(text); |
| } |
| } catch (IOException ex) { |
| LOG.log(Level.FINE, "Cannot print color or hyperlink", ex); //NOI18N |
| } |
| } |
| |
| @Override |
| public Lookup getIOLookup(InputOutput io) { |
| if (io instanceof Lookup.Provider) { |
| return ((Lookup.Provider) io).getLookup(); |
| } else { |
| return Lookup.EMPTY; |
| } |
| } |
| |
| @Override |
| public void resetIO(InputOutput io) { |
| try { |
| io.getOut().reset(); |
| } catch (IOException ex) { |
| LOG.log(Level.FINE, "Cannot reset InputOutput.", ex); //NOI18N |
| } |
| } |
| |
| @Override |
| public void showIO(InputOutput io, |
| Set<ShowOperation> operations) { |
| if (operations.contains(ShowOperation.OPEN) |
| && operations.contains(ShowOperation.MAKE_VISIBLE) |
| && operations.size() == 2) { |
| io.select(); |
| } else { |
| IOSelect.select(io, showOperationsToIoSelect(operations)); |
| } |
| } |
| |
| /** |
| * Translate set of {@link ShowOperation}s to set of |
| * {@link IOSelect.AdditionalOperation}s. |
| */ |
| private Set<IOSelect.AdditionalOperation> showOperationsToIoSelect( |
| Set<ShowOperation> operations) { |
| Set<IOSelect.AdditionalOperation> res |
| = EnumSet.noneOf(IOSelect.AdditionalOperation.class); |
| for (ShowOperation so : operations) { |
| switch (so) { |
| case OPEN: |
| res.add(IOSelect.AdditionalOperation.OPEN); |
| break; |
| case MAKE_VISIBLE: |
| res.add(IOSelect.AdditionalOperation.REQUEST_VISIBLE); |
| break; |
| case ACTIVATE: |
| res.add(IOSelect.AdditionalOperation.REQUEST_ACTIVE); |
| break; |
| } |
| } |
| return res; |
| } |
| |
| @Override |
| public void closeIO(InputOutput io) { |
| io.closeInputOutput(); |
| } |
| |
| @Override |
| public boolean isIOClosed(InputOutput io) { |
| return io.isClosed(); |
| } |
| |
| @Override |
| public Position getCurrentPosition(InputOutput io, OutputWriter writer) { |
| if (IOPosition.isSupported(io)) { |
| return IOPosition.currentPosition(io); |
| } else { |
| return null; |
| } |
| } |
| |
| @Override |
| public void scrollTo(InputOutput io, OutputWriter writer, Position position) { |
| position.scrollTo(); |
| } |
| |
| @Override |
| public FoldHandle startFold(InputOutput io, OutputWriter writer, |
| boolean expanded) { |
| |
| if (IOFolding.isSupported(io)) { |
| synchronized (foldStack) { |
| if (foldStack.isEmpty()) { |
| foldStack.addLast(IOFolding.startFold(io, expanded)); |
| } else { |
| foldStack.addLast(foldStack.getLast().startFold(expanded)); |
| } |
| return foldStack.getLast(); |
| } |
| } else { |
| return null; |
| } |
| } |
| |
| @Override |
| public void endFold(InputOutput io, OutputWriter writer, FoldHandle fold) { |
| synchronized (foldStack) { |
| while (!foldStack.isEmpty()) { |
| if (foldStack.removeLast() == fold) { |
| break; |
| } |
| } |
| fold.silentFinish(); |
| } |
| } |
| |
| @Override |
| public void setFoldExpanded(InputOutput io, OutputWriter writer, |
| FoldHandle fold, boolean expanded) { |
| fold.setExpanded(expanded); |
| } |
| |
| @Override |
| public String getIODescription(InputOutput io) { |
| if (IOTab.isSupported(io)) { |
| return IOTab.getToolTipText(io); |
| } else { |
| return null; |
| } |
| } |
| |
| @Override |
| public void setIODescription(InputOutput io, String description) { |
| if (IOTab.isSupported(io)) { |
| IOTab.setToolTipText(io, description); |
| } |
| } |
| |
| /** |
| * Convert a hyperlink to an output listener. |
| * |
| * @param link The hyperlink. |
| * @return The wrapping output listener. |
| */ |
| private static OutputListener hyperlinkToOutputListener( |
| final Hyperlink link) { |
| |
| if (link == null) { |
| return null; |
| } |
| return new OutputListenerAdapter() { |
| @Override |
| public void outputLineAction(OutputEvent ev) { |
| Hyperlinks.invoke(link); |
| } |
| }; |
| } |
| |
| /** |
| * Convert AWT-independent {@link OutputColor} to {@link java.awt.Color}. |
| * |
| * @return Appropriate color, or null if default color should be used. |
| */ |
| private static Color outputColorToAwtColor(InputOutput io, |
| OutputColor color) { |
| |
| if (color == null) { |
| return null; |
| } |
| OutputColorType type = OutputColors.getType(color); |
| if (type == OutputColorType.RGB) { |
| return new Color(OutputColors.getRGB(color)); |
| } else if (IOColors.isSupported(io)) { |
| switch (type) { |
| case DEBUG: |
| return IOColors.getColor(io, OutputType.LOG_DEBUG); |
| case FAILURE: |
| return IOColors.getColor(io, OutputType.LOG_FAILURE); |
| case WARNING: |
| return IOColors.getColor(io, OutputType.LOG_WARNING); |
| case SUCCESS: |
| return IOColors.getColor(io, OutputType.LOG_SUCCESS); |
| default: |
| return null; |
| } |
| } else { |
| return null; |
| } |
| } |
| |
| private static class OutputListenerAdapter implements OutputListener { |
| |
| @Override |
| public void outputLineSelected(OutputEvent ev) { |
| } |
| |
| @Override |
| public void outputLineAction(OutputEvent ev) { |
| } |
| |
| @Override |
| public void outputLineCleared(OutputEvent ev) { |
| } |
| } |
| } |