org.htmlunit.html.HtmlApplet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xlt Show documentation
Show all versions of xlt Show documentation
XLT (Xceptance LoadTest) is an extensive load and performance test tool developed and maintained by Xceptance.
The newest version!
/*
* Copyright (c) 2002-2024 Gargoyle Software Inc.
*
* Licensed 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
* https://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.htmlunit.html;
import java.applet.Applet;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.htmlunit.AppletConfirmHandler;
import org.htmlunit.FailingHttpStatusCodeException;
import org.htmlunit.SgmlPage;
import org.htmlunit.WebClient;
import org.htmlunit.WebRequest;
import org.htmlunit.WebResponse;
import org.htmlunit.html.applets.AppletClassLoader;
import org.htmlunit.html.applets.AppletStubImpl;
import org.htmlunit.util.UrlUtils;
/**
* Wrapper for the HTML element "applet".
*
* @author Mike Bowler
* @author David K. Taylor
* @author Christian Sell
* @author Ahmed Ashour
* @author Marc Guillemot
* @author Ronald Brill
* @author Frank Danek
*/
public class HtmlApplet extends HtmlElement {
private static final Log LOG = LogFactory.getLog(HtmlApplet.class);
private static final String ARCHIVE = "archive";
private static final String CACHE_ARCHIVE = "cache_archive";
private static final String CODEBASE = "codebase";
/** The HTML tag represented by this element. */
public static final String TAG_NAME = "applet";
private Applet applet_;
private List archiveUrls_;
/**
* Creates a new instance.
*
* @param qualifiedName the qualified name of the element type to instantiate
* @param page the page that contains this element
* @param attributes the initial attributes
*/
HtmlApplet(final String qualifiedName, final SgmlPage page,
final Map attributes) {
super(qualifiedName, page, attributes);
}
/**
* Returns the value of the attribute "codebase". Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute "codebase" or an empty string if that attribute isn't defined
*/
public final String getCodebaseAttribute() {
return getAttribute(CODEBASE);
}
/**
* Returns the value of the attribute {@code archive}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code archive} or an empty string if that attribute isn't defined
*/
public final String getArchiveAttribute() {
return getAttribute(ARCHIVE);
}
/**
* Returns the value of the attribute "code". Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute "code" or an empty string if that attribute isn't defined
*/
public final String getCodeAttribute() {
return getAttributeDirect("code");
}
/**
* Returns the value of the attribute {@code object}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code object} or an empty string if that attribute isn't defined
*/
public final String getObjectAttribute() {
return getAttributeDirect("object");
}
/**
* Returns the value of the attribute {@code alt}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code alt} or an empty string if that attribute isn't defined
*/
public final String getAltAttribute() {
return getAttributeDirect("alt");
}
/**
* Returns the value of the attribute {@code name}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code name} or an empty string if that attribute isn't defined
*/
public final String getNameAttribute() {
return getAttributeDirect(NAME_ATTRIBUTE);
}
/**
* Returns the value of the attribute {@code width}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code width} or an empty string if that attribute isn't defined
*/
public final String getWidthAttribute() {
return getAttributeDirect("width");
}
/**
* Returns the value of the attribute {@code height}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code height} or an empty string if that attribute isn't defined
*/
public final String getHeightAttribute() {
return getAttributeDirect("height");
}
/**
* Returns the value of the attribute {@code align}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code align} or an empty string if that attribute isn't defined
*/
public final String getAlignAttribute() {
return getAttributeDirect("align");
}
/**
* Returns the value of the attribute {@code hspace}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code hspace} or an empty string if that attribute isn't defined
*/
public final String getHspaceAttribute() {
return getAttributeDirect("hspace");
}
/**
* Returns the value of the attribute {@code vspace}. Refer to the
* HTML 4.01
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code vspace} or an empty string if that attribute isn't defined
*/
public final String getVspaceAttribute() {
return getAttributeDirect("vspace");
}
/**
* Gets the applet referenced by this tag. Instantiates it if necessary.
*
* @return the applet or null, if the installed AppletConfirmHandler
* prohibits this applet
* @throws IOException in case of problem
*/
public Applet getApplet() throws IOException {
setupAppletIfNeeded();
return applet_;
}
/**
* Download the associated content specified in the code attribute.
*
* @throws IOException if an error occurs while downloading the content
*/
@SuppressWarnings("unchecked")
private synchronized void setupAppletIfNeeded() throws IOException {
if (applet_ != null) {
return;
}
final HashMap params = new HashMap<>();
params.put(NAME_ATTRIBUTE, getNameAttribute());
params.put("object", getObjectAttribute());
params.put("align", getAlignAttribute());
params.put("alt", getAltAttribute());
params.put("height", getHeightAttribute());
params.put("hspace", getHspaceAttribute());
params.put("vspace", getVspaceAttribute());
params.put("width", getWidthAttribute());
final DomNodeList paramTags = getElementsByTagName("param");
for (final HtmlElement paramTag : paramTags) {
final HtmlParameter parameter = (HtmlParameter) paramTag;
params.put(parameter.getNameAttribute(), parameter.getValueAttribute());
}
if (StringUtils.isEmpty(params.get(CODEBASE)) && StringUtils.isNotEmpty(getCodebaseAttribute())) {
params.put(CODEBASE, getCodebaseAttribute());
}
if (StringUtils.isEmpty(params.get(ARCHIVE)) && StringUtils.isNotEmpty(getArchiveAttribute())) {
params.put(ARCHIVE, getArchiveAttribute());
}
final HtmlPage page = (HtmlPage) getPage();
final WebClient webclient = page.getWebClient();
final AppletConfirmHandler handler = webclient.getAppletConfirmHandler();
if (null != handler && !handler.confirm(this)) {
return;
}
String appletClassName = getCodeAttribute();
if (appletClassName.endsWith(".class")) {
appletClassName = appletClassName.substring(0, appletClassName.length() - 6);
}
try (AppletClassLoader appletClassLoader =
new AppletClassLoader(getPage().getEnclosingWindow().getScriptableObject(),
Thread.currentThread().getContextClassLoader())) {
final String documentUrl = page.getUrl().toExternalForm();
String baseUrl = UrlUtils.resolveUrl(documentUrl, ".");
final String codebaseProperty = params.get(CODEBASE);
if (StringUtils.isNotEmpty(codebaseProperty)) {
// codebase can be relative to the page
baseUrl = UrlUtils.resolveUrl(baseUrl, codebaseProperty);
}
if (!baseUrl.endsWith("/")) {
baseUrl = baseUrl + "/";
}
// check archive
final List archiveUrls = new ArrayList<>();
String[] archives = org.htmlunit.util.StringUtils.splitAtComma(params.get(ARCHIVE));
if (null != archives) {
for (final String tmpArchive : archives) {
final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive.trim());
final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
appletClassLoader.addArchiveToClassPath(archiveUrl);
archiveUrls.add(archiveUrl);
}
}
archives = org.htmlunit.util.StringUtils.splitAtComma(params.get(CACHE_ARCHIVE));
if (null != archives) {
for (final String tmpArchive : archives) {
final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive.trim());
final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
appletClassLoader.addArchiveToClassPath(archiveUrl);
archiveUrls.add(archiveUrl);
}
}
archiveUrls_ = Collections.unmodifiableList(archiveUrls);
// no archive attribute, single class
if (archiveUrls_.isEmpty()) {
final String tempUrl = UrlUtils.resolveUrl(baseUrl, getCodeAttribute());
final URL classUrl = UrlUtils.toUrlUnsafe(tempUrl);
final WebResponse response = webclient.loadWebResponse(new WebRequest(classUrl));
try {
webclient.throwFailingHttpStatusCodeExceptionIfNecessary(response);
appletClassLoader.addClassToClassPath(appletClassName, response);
}
catch (final FailingHttpStatusCodeException e) {
// that is what the browser does, the applet only fails, if
// the main class is not loadable
LOG.error(e.getMessage(), e);
}
}
try {
final Class