/******************************************************************************* * Copyright (c) 2008, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware Inc. - initial contribution *******************************************************************************/ package org.eclipse.virgo.shell.internal; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.InputStream; import java.io.PrintStream; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.eclipse.virgo.medic.log.DelegatingPrintStream; /** * <p> * LocalInputOutputManager can grab the system input and output streams from the service registry and block and release them * </p> * * <strong>Concurrent Semantics</strong><br /> * * LocalInputOutputManager is thread safe * */ public final class LocalInputOutputManager { private static final String SERVICE_FILTER_SYSERR_DELEGATE = "(org.eclipse.virgo.medic.log.printStream=delegating.System.err)"; private static final String SERVICE_FILTER_SYSOUT_DELEGATE = "(org.eclipse.virgo.medic.log.printStream=delegating.System.out)"; private final InputStream in; private final PrintStream out; private final PrintStream err; private final DelegatingPrintStream delegatingSysOut; private final DelegatingPrintStream delegatingSysErr; public LocalInputOutputManager(BundleContext bundleContext) { this.in = new FileInputStream(FileDescriptor.in); this.out = getPrintStreamFromServiceRegistry(bundleContext, "(org.eclipse.virgo.medic.log.printStream=System.out)"); this.err = getPrintStreamFromServiceRegistry(bundleContext, "(org.eclipse.virgo.medic.log.printStream=System.err)"); this.delegatingSysOut = getDelegatingPrintStreamFromServiceRegistry(bundleContext,SERVICE_FILTER_SYSOUT_DELEGATE); this.delegatingSysErr = getDelegatingPrintStreamFromServiceRegistry(bundleContext,SERVICE_FILTER_SYSERR_DELEGATE); } /** * */ public void grabSystemIO() { this.delegatingSysOut.setDelegate(null); this.delegatingSysErr.setDelegate(null); } /** * */ public void releaseSystemIO() { this.delegatingSysOut.setDelegate(this.out); this.delegatingSysErr.setDelegate(this.err); } /** * Get the original {@link PrintStream} for the local command line * @return PrintStream */ public PrintStream getErr() { return err; } /** * Get the original {@link PrintStream} for the local command line * @return PrintStream */ public PrintStream getOut() { return out; } /** * Get the original {@link InputStream} for the local command line * @return InputStream */ public InputStream getIn() { return in; } private static PrintStream getPrintStreamFromServiceRegistry(BundleContext bundleContext, String filter) { return (PrintStream) getService(PrintStream.class, bundleContext, filter); } private static DelegatingPrintStream getDelegatingPrintStreamFromServiceRegistry(BundleContext bundleContext, String filter) { return (DelegatingPrintStream) getService(DelegatingPrintStream.class, bundleContext, filter); } private static Object getService(Class<?> clazz, BundleContext bundleContext, String filter) { ServiceReference<?>[] serviceReferences; try { serviceReferences = bundleContext.getServiceReferences(clazz.getName(), filter); } catch (InvalidSyntaxException e) { throw new RuntimeException("Unexpected InvalidSyntaxException", e); } if (serviceReferences != null && serviceReferences.length > 0) { return bundleContext.getService(serviceReferences[0]); } else { return null; } } }