Java tutorial
/* * Copyright 2011-2016 CAST, Inc. * * This file is part of the CAST Wicket Modules: * see <http://code.google.com/p/cast-wicket-modules>. * * The CAST Wicket Modules are free software: you can redistribute and/or * modify them under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * The CAST Wicket Modules are distributed in the hope that they will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this software. If not, see <http://www.gnu.org/licenses/>. */ package org.cast.cwm.components; import java.io.File; import java.io.FilenameFilter; import javax.servlet.ServletContext; import org.apache.wicket.Application; import org.apache.wicket.RuntimeConfigurationType; import org.apache.wicket.SharedResources; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.MarkupStream; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.html.IHeaderContributor; import org.apache.wicket.markup.html.WebComponent; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.request.resource.ContextRelativeResource; import org.apache.wicket.request.resource.PackageResourceReference; import org.apache.wicket.util.file.Folder; import org.apache.wicket.util.value.IValueMap; import org.apache.wicket.util.value.ValueMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p>Wicket component to add the * <a href="http://java.sun.com/javase/6/docs/technotes/guides/jweb/deployment_advice.html">Sun's Deployment Toolkit</a> * Javascript. * The markup can be defined as any tag that will be replaced by the deployment script. Attributes * defined in the tag will be copied to the final applet tag by way of the deployment script.</p> * * <p> * Note: Sun's Deployment Toolkit does not work with AJAX. If this component is rendered during * an ajax call, uses a standard <applet> tag instead of Sun's deployment. * </p> * <p> * Suppose we have the following markup: * <pre> * <div wicket:id="applet" width=200 height=120 code="SignatureApplet.class" * archive="codesign.jar"></div> * </pre> * In a Wicket page we can create this component and add it to the page: * <pre> * DeployJava deployJava = new DeployJava("applet"); * add(deployJava); * </pre> * We get the following output: * <pre> * <html> * <head> * <script type="text/Javascript" src="http://java.com/js/deployJava.js"></script> * </head> * <body> * <script type="text/javascript"> * var attributes = { "width":200,"height":120,"code":"SignatureApplet.class","archive":"codesign.jar", "wicket:id":"applet"}; * var parameters = {}; * var version = null; * deployJava.runApplet(attributes, parameters, version); * </script> * <applet wicket:id="applet" ... > * ... * </applet> * </body> * </html> * </pre> * </p> * * Adapted from Mr. Haki's <a href="http://mrhaki.blogspot.com/2009/05/wicket-component-for-java-deployment.html">Post</a>. */ public class DeployJava extends WebComponent implements IHeaderContributor { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(DeployJava.class); /** * Javascript URL on Sun's website for deployJava Javascript. (={@value}) */ public static final String JAVASCRIPT_URL = "http://java.com/js/deployJava.js"; /** * Attribute to set the width of the applet. (={@value}) */ private static final String ATTRIBUTE_WIDTH = "width"; /** * Attribute to set the height of the applet. (={@value}) */ private static final String ATTRIBUTE_HEIGHT = "height"; /** * Attribute to set the applet classname. (={@value}) */ private static final String ATTRIBUTE_CODE = "code"; /** * Attribute to set the codebase for the applet. (={@value}) */ private static final String ATTRIBUTE_CODEBASE = "codebase"; /** * Attribute to set the archive neede by the applet. (={@value}) */ private static final String ATTRIBUTE_ARCHIVE = "archive"; /** * Minimal Java version needed for the applet. */ private String minimalVersion = "1.5"; /** * Attributes for the javaDeploy.runApplet Javascript method. */ private IValueMap appletAttributes = new ValueMap(); /** * Parameters for the javaDeploy.runApplet Javascript method. */ private IValueMap appletParameters = new ValueMap(); /** * Javascript that will be run if Java is not enabled in the browser. */ private String onJavaDisabled = ""; /** * Default constructor with markup id. * * @param id Markup id for applet. */ public DeployJava(String id) { super(id); } /** * Constructor that will load a certain jar and class as an applet. Will do its best * to search for a jar file beginning with "jarName" in the /WEB-INF/lib folder * and add it as a shared resource for this application, if necessary. * * Usage Example: new DeployJava("appletId", "awesome-applet", "org.example.Applet") * * The above example will find /WEB-INF/lib/awesome-applet-1.0-SNAPSHOT.jar and add it * as a shared resource under the DeployJava.class. * * @param id * @param jarName * @param className */ public DeployJava(String id, String jarName, String className) { super(id); if (Application.get().getConfigurationType().equals(RuntimeConfigurationType.DEVELOPMENT)) setArchive(getSharedArchiveURL(jarName) + "?" + System.currentTimeMillis()); else setArchive(getSharedArchiveURL(jarName)); setCode(className); } /** * Provides a URL to a shared resource for the given jarFile. If a resource * does not exist, it searches the /WEB-INF/lib folder for a file that starts with * the provided name and adds the resource first. * * @param jarName * @return */ public String getSharedArchiveURL(final String jarName) { SharedResources sr = Application.get().getSharedResources(); // If this jarName is not listed as a shared resource, add it as one. if (sr.get(DeployJava.class, jarName, null, null, null, false) == null) { ServletContext sc = WebApplication.get().getServletContext(); String path = "/WEB-INF/lib"; File jar = findMatchingFile(new Folder(sc.getRealPath(path)), jarName); if (jar == null) { path = "/WEB-INF/classes"; jar = findMatchingFile(new Folder(sc.getRealPath(path)), jarName); } if (jar == null) { log.error("No JAR found matching {}, looked in {} and {}", jarName, sc.getRealPath("/WEB-INF/lib"), sc.getRealPath("/WEB-INF/classes")); } else { log.debug("Adding JAR to Shared Resources: {}", jar.getAbsolutePath()); ContextRelativeResource resource = new ContextRelativeResource(path + "/" + jar.getName()); sr.add(DeployJava.class, jarName, null, null, null, resource); } } return urlFor(new PackageResourceReference(DeployJava.class, jarName), null).toString(); } // Look for a file beginning with the given prefix in the given folder. private File findMatchingFile(Folder folder, final String prefix) { File[] options = folder.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String file) { return (file.startsWith(prefix)); } }); if (options == null || options.length < 1) return null; return options[0]; } /** * Minimal Java version for the applet. E.g. Java 1.6 is "1.6" * * Default minimum version is Java 1.5. * * @param version Minimal Java version needed by the applet. */ public void setMinimalVersion(final String version) { this.minimalVersion = version; } /** * Width of the applet. * * @param width Width of the applet on screen. */ public void setWidth(final Integer width) { appletAttributes.put(ATTRIBUTE_WIDTH, width); } /** * Height of the applet. * * @param height Height of the applet on screen. */ public void setHeight(final Integer height) { appletAttributes.put(ATTRIBUTE_HEIGHT, height); } /** * Applet classname. * * @param code Applet classname. */ public void setCode(final String code) { appletAttributes.put(ATTRIBUTE_CODE, code); } /** * Codebase for the applet code. * * @param codebase Codebase for the applet code. */ public void setCodebase(final String codebase) { appletAttributes.put(ATTRIBUTE_CODEBASE, codebase); } /** * Archive path for the applet. * * @param archive Archive location for the applet. */ public void setArchive(final String archive) { appletAttributes.put(ATTRIBUTE_ARCHIVE, archive); } /** * Add a parameter to the applet. * * @param key Name of the parameter. * @param value Value for the parameter. */ public void addParameter(final String key, final Object value) { appletParameters.put(key, value); } /** * Add an attribute to the applet tag. * * @param key Name of the parameter. * @param value Value for the parameter. */ public void addAttribute(final String key, final Object value) { appletAttributes.put(key, value); } public void setAllowScripting(boolean b) { if (b) addAttribute("MAYSCRIPT", true); else appletAttributes.remove("MAYSCRIPT"); } public String getOnJavaDisabled() { return onJavaDisabled; } public void setOnJavaDisabled(String onJavaDisabled) { this.onJavaDisabled = onJavaDisabled; } /** * Get the attributes already set and assign them to the attribute * list for the Javascript code (or applet tag). And we change the tag name * to "script" or "applet" based on whether this is an Ajax call. * * @param tag the current tag which is replaced. */ @Override protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); // TODO: Get Sun and W3 to agree on some applet standards and use them here. final IValueMap tagAttributes = tag.getAttributes(); appletAttributes.putAll(tagAttributes); tagAttributes.clear(); AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class); if (target == null) { tag.setName("script"); tagAttributes.put("type", "text/javascript"); } else { tag.setName("applet"); tag.putAll(appletAttributes); } } /** * Create Javascript for deployJava.runApplet or applet parameters if this * is an ajax call. * * @param markupStream MarkupStream to be replaced. * @param openTag Tag we are replacing. */ @Override public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) { // If this is being directly rendered, use Sun's Deployment Toolkit. AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class); if (target == null) { final StringBuilder deployScript = new StringBuilder(); if (appletAttributes.size() > 0) { deployScript.append("var attributes = {"); for (String key : appletAttributes.keySet()) { deployScript.append("'" + key + "': '" + appletAttributes.get(key) + "', "); } deployScript.delete(deployScript.lastIndexOf(","), deployScript.length()); deployScript.append("};\n"); } else { deployScript.append("var attributes = {};\n"); } if (appletParameters.size() > 0) { deployScript.append("var parameters = {"); for (String key : appletParameters.keySet()) { deployScript.append("'" + key + "': '" + appletParameters.get(key) + "', "); } deployScript.delete(deployScript.lastIndexOf(","), deployScript.length()); deployScript.append("};\n"); } else { deployScript.append("var parameters = {};\n"); } if (minimalVersion != null) { deployScript.append("var version = \"" + minimalVersion + "\";\n"); } else { deployScript.append("var version = null;\n"); } deployScript.append(String.format( "if (navigator.javaEnabled()) { deployJava.runApplet(attributes, parameters, version); } else { %s }\n", onJavaDisabled)); replaceComponentTagBody(markupStream, openTag, deployScript.toString()); // Otherwise, just add the parameters. } else { final StringBuilder parameterList = new StringBuilder(); for (String key : appletParameters.keySet()) { parameterList.append("<param name='" + key + "' value='" + appletParameters.get(key) + "' />\n"); } replaceComponentTagBody(markupStream, openTag, parameterList.toString()); } } /** * Add Javascript src reference in the HTML head section of the web page. * * @param response Header response. */ @Override public void renderHead(IHeaderResponse response) { AjaxRequestTarget target = getRequestCycle().find(AjaxRequestTarget.class); if (target == null) response.render(JavaScriptHeaderItem.forUrl(JAVASCRIPT_URL)); } }