001 /*
002 * Created on Jul 14, 2008
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005 * the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011 * specific language governing permissions and limitations under the License.
012 *
013 * Copyright @2008-2010 the original author or authors.
014 */
015 package org.fest.swing.launcher;
016
017 import static org.fest.swing.edt.GuiActionRunner.execute;
018 import static org.fest.swing.launcher.NewAppletViewerQuery.showAppletViewerWith;
019 import static org.fest.util.Strings.concat;
020 import static org.fest.util.Strings.isEmpty;
021
022 import java.applet.Applet;
023 import java.applet.AppletStub;
024 import java.util.HashMap;
025 import java.util.Map;
026
027 import org.fest.swing.annotation.RunsInEDT;
028 import org.fest.swing.applet.AppletViewer;
029 import org.fest.swing.applet.BasicAppletContext;
030 import org.fest.swing.applet.BasicAppletStub;
031 import org.fest.swing.edt.GuiQuery;
032 import org.fest.swing.exception.UnexpectedException;
033 import org.fest.swing.launcher.AppletParameter.AppletParameterBuilder;
034
035 /**
036 * Understands a fluent interface for launching and testing <code>{@link Applet}</code>s.
037 * <p>
038 * An applet can be launched by passing its type as <code>String</code>, the actual type, or an instance of the
039 * applet to launch:
040 *
041 * <pre>
042 * {@link AppletViewer} viewer = AppletLauncher.{@link #applet(String) applet}("org.fest.swing.applet.MyApplet").{@link #start() start}();
043 *
044 * // or
045 *
046 *
047 * {@link AppletViewer} viewer = AppletLauncher.{@link #applet(Class) applet}(MyApplet.class).{@link #start() start}();
048 *
049 * // or
050 *
051 * {@link AppletViewer} viewer = AppletLauncher.{@link #applet(Applet) applet}(new MyApplet()).{@link #start() start}();
052 * </pre>
053 *
054 * </p>
055 * <p>
056 * In addition, we can pass parameters to the applet to launch. The parameters to pass are the same that are specified
057 * in the <a href="http://java.sun.com/docs/books/tutorial/deployment/applet/html.html"
058 * target="_blank">HTML "param" tag</a>:
059 *
060 * <pre>
061 * {@link AppletViewer} viewer = AppletLauncher.{@link #applet(Applet) applet}(new MyApplet())
062 * .{@link #withParameters(Map) withParameters}(
063 * {@link AppletParameter#name(String) name}("bgcolor").{@link AppletParameterBuilder#value(String) value}("blue"),
064 * {@link AppletParameter#name(String) name}("color").{@link AppletParameterBuilder#value(String) value}("red"),
065 * {@link AppletParameter#name(String) name}("pause").{@link AppletParameterBuilder#value(String) value}("200")
066 * )
067 * .{@link #start() start}();
068 *
069 * // or
070 *
071 * Map<String, String> parameters = new HashMap<String, String>();
072 * parameters.put("bgcolor", "blue");
073 * parameters.put("color", "red");
074 * parameters.put("pause", "200");
075 *
076 * {@link AppletViewer} viewer = AppletLauncher.{@link #applet(Applet) applet}(new MyApplet()).{@link #withParameters(Map) withParameters}(parameters).{@link #start() start}();
077 *
078 *
079 * </pre>
080 *
081 * </p>
082 *
083 *
084 * @author Yvonne Wang
085 * @author Alex Ruiz
086 */
087 public class AppletLauncher {
088
089 private final Applet applet;
090 private final Map<String, String> parameters = new HashMap<String, String>();
091
092 /**
093 * Creates a new applet launcher. The applet to launch is a new instance of the given type. It is assumed that the
094 * given type has a default constructor.
095 * @param appletType the type of applet to instantiate.
096 * @return the created applet launcher.
097 * @throws NullPointerException if the given type name is <code>null</code>.
098 * @throws IllegalArgumentException if the given type name is empty.
099 * @throws IllegalArgumentException if the given type is not a subclass of <code>java.applet.Applet</code>.
100 * @throws UnexpectedException if the given type cannot be loaded.
101 * @throws UnexpectedException if a new instance of the given type cannot be instantiated.
102 */
103 @RunsInEDT
104 public static AppletLauncher applet(String appletType) {
105 if (appletType == null) throw new NullPointerException("The name of the applet type should not be null");
106 if (isEmpty(appletType)) throw new IllegalArgumentException("The name of the applet type should not be empty");
107 Class<?> type = load(appletType);
108 if (!(Applet.class.isAssignableFrom(type)))
109 throw new IllegalArgumentException(concat("The given type is not a subclass of ", Applet.class.getName()));
110 return instantiate(type);
111 }
112
113 @RunsInEDT
114 private static Class<?> load(String typeName) {
115 try {
116 return Class.forName(typeName);
117 } catch (ClassNotFoundException e) {
118 throw cannotLoadType(typeName, e);
119 } catch (Exception e) {
120 throw cannotLoadType(typeName, e);
121 }
122 }
123
124 private static UnexpectedException cannotLoadType(String typeName, Exception e) {
125 throw new UnexpectedException(concat("Unable to load class ", typeName), e);
126 }
127
128 /**
129 * Creates a new applet launcher. The applet to launch is a new instance of the given type. It is assumed that the
130 * given type has a default constructor.
131 * @param appletType the type of applet to instantiate.
132 * @return the created applet launcher.
133 * @throws NullPointerException if the given type is <code>null</code>.
134 * @throws UnexpectedException if a new instance of the given type cannot be instantiated.
135 */
136 @RunsInEDT
137 public static AppletLauncher applet(Class<? extends Applet> appletType) {
138 if (appletType == null) throw new NullPointerException("The applet type should not be null");
139 return instantiate(appletType);
140 }
141
142 private static AppletLauncher instantiate(final Class<?> appletType) {
143 try {
144 Object applet = execute(new GuiQuery<Object>() {
145 protected Object executeInEDT() throws Exception {
146 return appletType.newInstance();
147 }
148 });
149 return applet((Applet)applet);
150 } catch (Exception e) {
151 throw cannotInstantiateApplet(appletType.getName(), e);
152 }
153 }
154
155 private static UnexpectedException cannotInstantiateApplet(String appletType, Exception cause) {
156 throw new UnexpectedException(concat("Unable to create a new instance of ", appletType), cause);
157 }
158
159 /**
160 * Creates a new applet launcher.
161 * @param applet the applet to launch.
162 * @return the created applet launcher.
163 * @throws NullPointerException if the given applet is <code>null</code>.
164 */
165 public static AppletLauncher applet(Applet applet) {
166 return new AppletLauncher(applet);
167 }
168
169 private AppletLauncher(Applet applet) {
170 if (applet == null) throw new NullPointerException("The applet to launch should not be null");
171 this.applet = applet;
172 }
173
174 /**
175 * Sets the parameters for the applet to launch, as an alternative to
176 * <code>{@link #withParameters(AppletParameter...)}</code>.
177 * @param newParameters the parameters for the applet to launch.
178 * @return this launcher.
179 * @throws NullPointerException if <code>newParameters</code> is <code>null</code>.
180 */
181 public AppletLauncher withParameters(Map<String, String> newParameters) {
182 if (newParameters == null) throw new NullPointerException("The map of parameters should not be null");
183 parameters.clear();
184 parameters.putAll(newParameters);
185 return this;
186 }
187
188 /**
189 * Sets the parameters for the applet to launch, as an alternative to <code>{@link #withParameters(Map)}</code>.
190 * @param newParameters the parameters for the applet to launch.
191 * @return this launcher.
192 * @throws NullPointerException if <code>newParameters</code> is <code>null</code>.
193 * @throws NullPointerException if any parameter is <code>null</code>.
194 */
195 public AppletLauncher withParameters(AppletParameter... newParameters) {
196 if (newParameters == null) throw new NullPointerException("The array of parameters should not be null");
197 parameters.clear();
198 for (AppletParameter parameter : newParameters) add(parameter);
199 return this;
200 }
201
202 private void add(AppletParameter parameter) {
203 if (parameter == null) throw new NullPointerException("Found a null parameter");
204 parameters.put(parameter.name, parameter.value);
205 }
206
207 /**
208 * Launches the applet in a <code>{@link AppletViewer}</code> (using implementations of
209 * <code>{@link BasicAppletStub}</code> and <code>{@link BasicAppletContext}</code>. To provide your own
210 * <code>{@link AppletStub}</code> create a new <code>{@link AppletViewer}</code> directly.
211 * The <code>AppletViewer</code> is created and launched in the event dispatch thread.
212 * @return the created <code>AppletViewer</code>.
213 */
214 public AppletViewer start() {
215 return showAppletViewerWith(applet, parameters);
216 }
217 }