 /**
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * Copyright © 2009 Mindoo GmbH
 *
 * @author Tammo Riedinger
 *
 */
package com.mindoo.ec09.example1;

import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;

import javax.swing.JApplet;
import javax.swing.JComponent;

import org.eclipse.albireo.core.SwingControl;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

/**
 * This sample demonstrates a simple life-cycle of a Swing application being integrated as a single view
 * into the Lotus Notes client.
 *  
 * @author Tammo Riedinger
 */
public class SampleView extends ViewPart {
	/**
	 * Member to hold a reference to the displayed control.
	 */
	private SwingControl control;
	/**
	 * Member to hold a reference to the applet being generated.
	 * This reference is used to free any resources used by the applet
	 * when the ViewPart is disposed.
	 * In this case, the applet-reference can be regarded as a bridge to the running application.
	 */
	private JApplet applet;

	@Override
	public void createPartControl(final Composite parent) {
		// start of life-cycle
		// Initialize the application and reposition its main-component
		// to the SwingControl (e.g. return the main-component in SwingControl#createSwingComponent()).
		control=new SwingControl(parent, SWT.NONE) {
			@Override
			protected JComponent createSwingComponent() {
				// Since we wanted to show a big set of swing-control in an RCP application,
				// we aimed to integrate SwingSet2.
				// Due to Sun's licensing, we are not be permitted to modify any
				// of its source-code.
				// Hence we have to use the applet-version of the SwingSet2 example and "abuse" its content-pane.
				try {
					// locate SwingSet2.jar
					final URL[] urls = new URL[] {
							FileLocator.toFileURL(Activator.getDefault().getBundle().getEntry("lib/SwingSet2.jar"))
					};
					
					// and load the applet
					URLClassLoader classLoader = AccessController.doPrivileged(
							new PrivilegedAction<URLClassLoader>() {
								public URLClassLoader run() {
									return new URLClassLoader(urls);
								}
							});
					
					applet = (JApplet)classLoader.loadClass("SwingSet2Applet").newInstance();
				} catch (Throwable t) {
					throw new RuntimeException(t);
				}

				// initialize the applet
				applet.init();
				applet.start();

				// return the content-pane of the applet to be displayed inside the Swing-Control
				return (JComponent)applet.getContentPane();
			}

			@Override
			public Composite getLayoutAncestor() {
				return parent;
			}

		};
	}

	@Override
	public void dispose() {
		// shut-down the instance of your legacy-application, 
		// when the last related ViewPart
		// in this case we use one instance per ViewPart
		super.dispose();

		if (applet!=null) {
			// shut-down the applet
			// This is easy here, since applets are designed to be shut-down without shutting down the JVM.
			// If you have a stand-alone legacy application, you would probably need to remove a
			// System.exit-call and think of a way to dispose singletons and static data.
			
			applet.stop();
			applet.destroy();
		}
		// end of life-cycle
	}

	@Override
	public void setFocus() {
		// hand the focus over to the control, whenever the ViewPart receives the focus
		if (control!=null && !control.isDisposed())
			control.setFocus();
	}
}