summaryrefslogtreecommitdiffstats
path: root/tdehtml/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'tdehtml/java/org')
-rw-r--r--tdehtml/java/org/kde/javascript/JSObject.java183
-rw-r--r--tdehtml/java/org/kde/kjas/server/Console.java20
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASAppletClassLoader.java360
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASAppletContext.java473
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASAppletPanel.java113
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASAppletStub.java807
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASAudioClip.java98
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASBrokenClassFixer.java132
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASConsole.java93
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASConsoleStream.java46
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASProtocolHandler.java900
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASSecurityManager.java243
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASSoundPlayer.java36
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASSwingConsole.java325
-rw-r--r--tdehtml/java/org/kde/kjas/server/KJASURLStreamHandlerFactory.java609
-rw-r--r--tdehtml/java/org/kde/kjas/server/Main.java178
-rw-r--r--tdehtml/java/org/kde/kjas/server/StatusListener.java5
17 files changed, 4621 insertions, 0 deletions
diff --git a/tdehtml/java/org/kde/javascript/JSObject.java b/tdehtml/java/org/kde/javascript/JSObject.java
new file mode 100644
index 000000000..11e7f9f99
--- /dev/null
+++ b/tdehtml/java/org/kde/javascript/JSObject.java
@@ -0,0 +1,183 @@
+package org.kde.javascript;
+
+import java.applet.Applet;
+import org.kde.kjas.server.KJASAppletContext;
+import org.kde.kjas.server.Main;
+
+public class JSObject extends netscape.javascript.JSObject {
+ public String returnvalue = null;
+ public Thread thread;
+
+ private String jsobject;
+ private int id;
+ private Applet applet;
+ private String appletID = null;
+
+ /* JavaScript code:
+ * __lc=[[JS objects],call func(index,script,appletname,isglobal)]
+ */
+ private final static String decls = "if(!window.__lc) window.__lc=[[window],function(i,s,a,g){var v;var len=window.__lc[0].length;if(i>=len)v='E unknown object';else{var r;try{r=eval((g?'':'window.__lc[0][i]')+s);}catch(e){v='E '+e;r='E ';}finally{var t=typeof r;if(t=='undefined')v='V ';else if(t=='number')v='N '+r;else if(t=='string'){if(r!='E ')v='S '+r;}else{window.__lc[0][len]=r;v=''+len+' '+(r==window.__lc?'[array]':r);}}}a.__lc_ret=v},0]";
+
+ public JSObject(Applet a, String name, int _id) {
+ Main.info("JSObject.ctor: " + name);
+ jsobject = new String(name);
+ applet = a;
+ id = _id;
+ KJASAppletContext kc = (KJASAppletContext)applet.getAppletContext();
+ appletID = kc.getAppletID(a);
+ if (id == 0) {
+ kc.evaluateJavaScript(decls, appletID, null);
+ }
+ }
+
+ int getId() {
+ return id;
+ }
+
+ private String escapeString(String string) {
+ StringBuffer sb = new StringBuffer();
+ int idx = 0;
+ boolean cr = false;
+ char [] chars = string.toCharArray();
+ while (idx < chars.length) {
+ if (cr && chars[idx] != '\n') {
+ cr = false;
+ sb.append("\\n");
+ }
+ switch (chars[idx]) {
+ case '\\':
+ sb.append("\\\\");
+ break;
+ case '"':
+ sb.append("\\\"");
+ break;
+ case '\n':
+ cr = false;
+ sb.append("\\n");
+ break;
+ case '\r':
+ cr = true;
+ break;
+ default:
+ sb.append(chars[idx]);
+ }
+ idx++;
+ }
+ if (cr)
+ sb.append("\\n");
+ return sb.toString();
+ }
+
+ private Object evaluate(String script, boolean global) throws netscape.javascript.JSException {
+ Main.info("evaluate (\"" + script + "\")");
+
+ KJASAppletContext kc = (KJASAppletContext) applet.getAppletContext();
+ //String appletname = kc.getAppletName(appletID);
+ thread = Thread.currentThread();
+
+ if (!kc.evaluateJavaScript("window.__lc[1](" + id + ",\"" + escapeString(script) + "\",this" + (global ? ",true)" : ")"), appletID, this)) {
+ Main.debug("evaluate on not active applet");
+ return null;
+ }
+ boolean timedout = true;
+ try {
+ Thread.sleep(30000);
+ } catch (InterruptedException ex) {
+ timedout = false;
+ }
+ thread = null;
+ if (timedout || returnvalue == null)
+ return null;
+
+ /* lets see what we've got */
+ String retval = returnvalue;
+ int pos = retval.indexOf(' ');
+ String type = retval.substring(0, pos);
+ if (type.equals("V")) // Void
+ return null;
+ String value = retval.substring(pos+1);
+ if (type.equals("E")) // Error
+ throw new netscape.javascript.JSException("Script error: " + value);
+ Main.info("value=" + value + " (type=" + type + ")");
+ if (type.equals("N")) // Number
+ return new Double(value);
+ if (type.equals("S")) // String
+ return value;
+
+ /* Is it an applet? */
+ if (value.startsWith("[object APPLET ref=")) {
+ int p1 = value.indexOf('=');
+ int p2 = value.indexOf(']', p1+1);
+ int applethashcode = Integer.parseInt(value.substring(p1+1, p2));
+ java.util.Enumeration e = kc.getApplets();
+ while (e.hasMoreElements()) {
+ Applet app = (Applet) e.nextElement();
+ if (app.hashCode() == applethashcode)
+ return app;
+ }
+ return null;
+ }
+ /* Is it a Java object then? */
+ if (value.startsWith("[object ") && value.indexOf("ref=") > 0) {
+ int p1 = value.indexOf("ref=");
+ int p2 = value.indexOf(']', p1+4);
+ int objecthashcode = Integer.parseInt(value.substring(p1+4, p2));
+ return kc.getJSReferencedObject(applet, objecthashcode);
+ }
+ /* Ok, make it a JSObject */
+ return new JSObject(applet, value, Integer.parseInt(type));
+ }
+ private String convertValueJ2JS(Object o) {
+ if (o == null)
+ return new String("null");
+ if (o instanceof java.lang.Number || o instanceof java.lang.Boolean)
+ return o.toString();
+ if (o instanceof netscape.javascript.JSObject)
+ return new String("window.__lc[0][" + ((JSObject)o).getId() + "]");
+ return new String("\"" + escapeString(o.toString()) + "\"");
+ }
+ public Object call(String func, Object [] args) throws netscape.javascript.JSException {
+ Main.info("JSObject.call: " + jsobject + "." + func);
+ String script = new String("." + func + "(");
+ for (int i = 0; args != null && i < args.length; i++)
+ script += (i > 0 ? "," : "") + convertValueJ2JS(args[i]);
+ script += ")";
+ return evaluate(script, false);
+ }
+ public Object eval(String s) throws netscape.javascript.JSException {
+ return evaluate(s, true);
+ }
+ public boolean equals(Object obj) {
+ Main.info("JSObject.equals");
+ return super.equals(obj);
+ }
+ public Object getMember(String name) throws netscape.javascript.JSException {
+ Main.info("JSObject.getMember: " + jsobject + "." + name);
+ return evaluate("." + name, false);
+ }
+ public void setMember(String name, java.lang.Object o) throws netscape.javascript.JSException {
+ Main.info("JSObject.setMember: " + jsobject + "." + name);
+ evaluate("." + name + "=" + convertValueJ2JS(o), false);
+ }
+ public void removeMember(String name) throws netscape.javascript.JSException {
+ Main.info("JSObject.removeMember: " + jsobject + "." + name);
+ evaluate("." + name + "=null", false);
+ }
+ /* get array element; JS: this[index] */
+ public Object getSlot(int index)throws netscape.javascript.JSException {
+ Main.info("JSObject.getSlot: " + jsobject + "[" + index + "]");
+ return evaluate("[" + index + "]", false);
+ }
+ public void setSlot(int index, Object o) throws netscape.javascript.JSException {
+ Main.info("JSObject.setSlot: " + jsobject + "[" + index + "]");
+ evaluate("[" + index + "]=" + convertValueJ2JS(o), false);
+ }
+ public String toString(){
+ Main.info("JSObject.toString: " + jsobject);
+ return new String(jsobject);
+ }
+ public static JSObject getWindow(Applet a, int dummy) {
+ Main.info("JSObject.getWindow");
+ return new JSObject(a, "[WINDOW]", 0);
+ }
+}
diff --git a/tdehtml/java/org/kde/kjas/server/Console.java b/tdehtml/java/org/kde/kjas/server/Console.java
new file mode 100644
index 000000000..d089f3cd8
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/Console.java
@@ -0,0 +1,20 @@
+/*
+ * Appendable.java
+ *
+ * Created on 16. Mai 2002, 23:23
+ */
+
+package org.kde.kjas.server;
+
+/**
+ *
+ * @author till
+ */
+public interface Console {
+
+ public void clear();
+ public void append(String text);
+
+ public void setVisible(boolean visible);
+
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASAppletClassLoader.java b/tdehtml/java/org/kde/kjas/server/KJASAppletClassLoader.java
new file mode 100644
index 000000000..c6defa848
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASAppletClassLoader.java
@@ -0,0 +1,360 @@
+package org.kde.kjas.server;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+import java.util.jar.*;
+import java.security.*;
+/**
+ * ClassLoader used to download and instantiate Applets.
+ * <P>
+ * NOTE: The class loader extends Java 1.2 specific class.
+ */
+public final class KJASAppletClassLoader
+ extends URLClassLoader
+{
+ private static Hashtable loaders = new Hashtable();
+
+ public static synchronized void removeLoaders()
+ {
+ loaders.clear();
+ }
+
+ public static synchronized KJASAppletClassLoader getLoader( String docBase, String codeBase, String archives )
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkCreateClassLoader();
+ }
+ URL docBaseURL;
+ KJASAppletClassLoader loader = null;
+ try
+ {
+ docBaseURL = new URL( docBase );
+
+ URL codeBaseURL = getCodeBaseURL( docBaseURL, codeBase );
+ String key = codeBaseURL.toString();
+ if (archives != null)
+ key += archives;
+
+ Main.debug( "CL: getLoader: key = " + key );
+
+ loader = (KJASAppletClassLoader) loaders.get( key );
+ if( loader == null )
+ {
+ URL [] urlList = {};
+ loader = new KJASAppletClassLoader( urlList, docBaseURL, codeBaseURL);
+ loaders.put( key, loader );
+ }
+ else
+ {
+ Main.debug( "CL: reusing classloader" );
+ }
+ } catch( MalformedURLException e ) { Main.kjas_err( "bad DocBase URL", e ); }
+ return loader;
+ }
+
+ public static URL getCodeBaseURL( URL docBaseURL, String codeBase )
+ {
+ URL codeBaseURL = null;
+ try
+ {
+ //first determine what the real codeBase is: 3 cases
+ //#1. codeBase is absolute URL- use that
+ //#2. codeBase is relative to docBase, create url from those
+ //#3. last resort, use docBase as the codeBase
+ if(codeBase != null)
+ {
+ //we need to do this since codeBase should be a directory
+ if( !codeBase.endsWith("/") )
+ codeBase = codeBase + "/";
+
+ try
+ {
+ codeBaseURL = new URL( codeBase );
+ } catch( MalformedURLException mue )
+ {
+ try
+ {
+ codeBaseURL = new URL( docBaseURL, codeBase );
+ } catch( MalformedURLException mue2 ) {}
+ }
+ }
+
+ if(codeBaseURL == null)
+ {
+ //fall back to docBase but fix it up...
+ String file = docBaseURL.getFile();
+ if( file == null || (file.length() == 0) )
+ codeBaseURL = docBaseURL;
+ else if( file.endsWith( "/" ) )
+ codeBaseURL = docBaseURL;
+ else
+ {
+ //delete up to the ending '/'
+ String urlString = docBaseURL.toString();
+ int dot_index = urlString.lastIndexOf( '/' );
+ String newfile = urlString.substring( 0, dot_index+1 );
+ codeBaseURL = new URL( newfile );
+ }
+ }
+ }catch( Exception e ) { Main.kjas_err( "CL: exception ", e ); }
+ return codeBaseURL;
+ }
+
+ public static KJASAppletClassLoader getLoader( String key )
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkCreateClassLoader();
+ }
+ if( loaders.containsKey( key ) )
+ return (KJASAppletClassLoader) loaders.get( key );
+
+ return null;
+ }
+
+ /*********************************************************************************
+ ****************** KJASAppletClassLoader Implementation *************************
+ **********************************************************************************/
+ private URL docBaseURL;
+ private URL codeBaseURL;
+ private Vector archives;
+ private String dbgID;
+ private static int globalId = 0;
+ private int myId = 0;
+ private Vector statusListeners = new Vector();
+ private AccessControlContext acc;
+ // a mapping JS referenced Java objects
+ private Hashtable jsReferencedObjects = new Hashtable();
+ final static RuntimePermission kjas_access = new RuntimePermission("accessClassInPackage.org.kde.kjas.server");
+
+ public KJASAppletClassLoader( URL[] urlList, URL _docBaseURL, URL _codeBaseURL)
+ {
+ super(urlList);
+ acc = AccessController.getContext();
+ synchronized(KJASAppletClassLoader.class) {
+ myId = ++globalId;
+ }
+ docBaseURL = _docBaseURL;
+ codeBaseURL = _codeBaseURL;
+ archives = new Vector();
+
+ dbgID = "CL-" + myId + "(" + codeBaseURL.toString() + "): ";
+ }
+
+ protected void addURL(URL url) {
+ Main.debug(this + " add URL: " + url);
+ super.addURL(url);
+ }
+
+ public void addStatusListener(StatusListener lsnr) {
+ statusListeners.add(lsnr);
+ }
+ public void removeStatusListener(StatusListener lsnr) {
+ statusListeners.remove(lsnr);
+ }
+ public void showStatus(String msg) {
+ Enumeration en = statusListeners.elements();
+ while (en.hasMoreElements()) {
+ StatusListener lsnr = (StatusListener)en.nextElement();
+ lsnr.showStatus(msg);
+ }
+ }
+
+ public void paramsDone() {
+ // simply builds up the search path
+ // put the archives first because they are
+ // cached.
+ for( int i = 0; i < archives.size(); ++i ) {
+ String jar = (String)archives.elementAt( i );
+ try {
+ URL jarURL = new URL(codeBaseURL, jar);
+ addURL(jarURL);
+ Main.debug("added archive URL \"" + jarURL + "\" to KJASAppletClassLoader");
+ } catch (MalformedURLException e) {
+ Main.kjas_err("Could not construct URL for jar file: " + codeBaseURL + " + " + jar, e);
+ }
+ }
+ // finally add code base url and docbase url
+ addURL(codeBaseURL);
+
+ // the docBaseURL has to be fixed.
+ // strip file part from end otherwise this
+ // will be interpreted as an archive
+ // (should this perhaps be done generally ??)
+ String dbs = docBaseURL.toString();
+ int idx = dbs.lastIndexOf("/");
+ if (idx > 0) {
+ dbs = dbs.substring(0, idx+1);
+ }
+ URL docDirURL = null;
+ try {
+ docDirURL = new URL(dbs);
+ } catch (MalformedURLException e) {
+ Main.debug("Could not make a new URL from docBaseURL=" + docBaseURL);
+ }
+ if (docDirURL != null && !codeBaseURL.equals(docDirURL)) {
+ addURL(docDirURL);
+ }
+ }
+
+ void addArchiveName( String jarname )
+ {
+ if( !archives.contains( jarname ) )
+ {
+ archives.add( jarname );
+ }
+ }
+
+
+ public URL getDocBase()
+ {
+ return docBaseURL;
+ }
+
+ public URL getCodeBase()
+ {
+ return codeBaseURL;
+ }
+
+ Hashtable getJSReferencedObjects() {
+ return jsReferencedObjects;
+ }
+ /***************************************************************************
+ **** Class Loading Methods
+ **************************************************************************/
+ public synchronized Class findClass( String name ) throws ClassNotFoundException
+ {
+ Class rval = null;
+ //check the loaded classes
+ rval = findLoadedClass( name );
+ if( rval == null ) {
+ try {
+ rval = super.findClass(name);
+ } catch (ClassFormatError cfe) {
+ Main.debug(name + ": Catched " + cfe + ". Trying to repair...");
+ rval = loadFixedClass( name );
+ } catch (Exception ex) {
+ Main.debug("findClass " + name + " " + ex.getMessage());
+ }
+ }
+ if (rval == null) {
+ throw new ClassNotFoundException("Class: " + name);
+ }
+ return rval;
+ }
+ public Class loadClass(String name) throws ClassNotFoundException {
+ if (name.startsWith("org.kde.kjas.server")) {
+ SecurityManager sec = System.getSecurityManager();
+ if (sec != null)
+ sec.checkPermission(kjas_access);
+ }
+ return super.loadClass(name);
+ }
+ private Hashtable loadedClasses = new Hashtable();
+
+ private synchronized final Class loadFixedClass(String name) throws ClassNotFoundException {
+ final String fileName = name.replace('.', '/') + ".class";
+ try {
+ // try to get the class as resource
+ final URL u = getResource(fileName);
+ Main.debug(dbgID + name + ": got URL: " + u);
+ if (u == null) {
+ throw new ClassNotFoundException(fileName + ": invalid resource URL.");
+ }
+ java.security.cert.Certificate[] certs = {}; // FIXME
+ CodeSource cs = new CodeSource(u, certs);
+ InputStream instream = (InputStream)AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ try {
+ return u.openStream();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ return null;
+ }
+ }
+ }, acc
+ );
+ if (instream == null) {
+ throw new ClassNotFoundException(name + ": could not be loaded.");
+ }
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ int cnt;
+ int total = 0;
+ int bufSize = 1024;
+ byte [] buffer = new byte[bufSize];
+ while ((cnt = instream.read(buffer, 0, bufSize)) > 0) {
+ total += cnt;
+ byteStream.write(buffer, 0, cnt);
+ }
+ Main.debug(dbgID + name + ": " + total + " bytes");
+
+ Class cl = fixAndDefineClass(name, byteStream.toByteArray(), 0, total, cs);
+ if (cl != null) {
+ loadedClasses.put(name, cl);
+ }
+ return cl;
+
+ } catch (Throwable e) {
+ e.printStackTrace();
+ throw new ClassNotFoundException("triggered by " + e);
+ }
+ }
+
+ public URL findResource( String name)
+ {
+ Main.debug( dbgID + "findResource, name = " + name );
+ String displayName = name;
+ try {
+ URL u = new URL(name);
+ String filename = u.getFile();
+ if (filename != null && filename.length() > 0) {
+ displayName = filename;
+ }
+ } catch (Throwable e) {
+ }
+ showStatus("Loading: " + displayName);
+ URL url = super.findResource( name );
+ Main.debug("findResource for " + name + " returns " + url);
+ return url;
+ }
+
+ protected PermissionCollection getPermissions(CodeSource cs) {
+ Main.debug(dbgID + " getPermissions(" + cs + ")");
+ PermissionCollection permissions = super.getPermissions(cs);
+ Enumeration perms_enum = permissions.elements();
+ while (perms_enum.hasMoreElements()) {
+ Main.debug(this + " Permission: " + perms_enum.nextElement());
+ }
+ return permissions;
+ }
+
+
+ /**
+ * define the class <b>name</b>. If <b>name</b> is broken, try to fix it.
+ */
+ private final Class fixAndDefineClass(
+ String name,
+ byte[] b,
+ int off,
+ int len,
+ CodeSource cs) throws ClassFormatError
+ {
+ KJASBrokenClassFixer fixer = new KJASBrokenClassFixer();
+ if (fixer.process(b, off, len)) {
+ Main.debug(name + " fixed");
+ } else {
+ Main.info(name + " could not be fixed");
+ }
+ return defineClass(name,
+ fixer.getProcessedData(),
+ fixer.getProcessedDataOffset(),
+ fixer.getProcessedDataLength(),
+ cs);
+ }
+
+
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASAppletContext.java b/tdehtml/java/org/kde/kjas/server/KJASAppletContext.java
new file mode 100644
index 000000000..f868b7b64
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASAppletContext.java
@@ -0,0 +1,473 @@
+package org.kde.kjas.server;
+
+import java.applet.*;
+import java.util.*;
+import java.net.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import org.kde.javascript.JSObject;
+
+final class KJASAuthenticator extends Authenticator {
+ private Hashtable authentication;
+
+ KJASAuthenticator() {
+ authentication = new Hashtable();
+ setDefault(this);
+ }
+ final void addURL(URL url, String user, String password, String authname) {
+ String key = new String(url.getProtocol() + ":" + url.getHost() + ":" +
+ url.getPort() + "_" + authname);
+ String [] auths = { user, password };
+ authentication.put(key, auths);
+ }
+ final protected PasswordAuthentication getPasswordAuthentication() {
+ URL url;
+ String key = new String(getRequestingProtocol() + ":" + getRequestingHost() + ":" + getRequestingPort() + "_" + getRequestingPrompt());
+ String [] auths = (String []) authentication.get(key);
+ if (auths != null) {
+ char [] pw = new char[auths[1].length()];
+ auths[1].getChars(0, auths[1].length(), pw, 0);
+ return new PasswordAuthentication(auths[0], pw);
+ }
+ return null;
+ }
+}
+
+/**
+ * The context in which applets live.
+ */
+public class KJASAppletContext implements AppletContext
+{
+ private Hashtable stubs;
+ private Hashtable images;
+ private Vector pendingImages;
+ private Hashtable streams;
+ private Stack jsobjects;
+
+ private String myID;
+ private KJASAppletClassLoader loader;
+ private boolean active;
+ private final static KJASAuthenticator authenticator = new KJASAuthenticator();
+
+ /**
+ * Create a KJASAppletContext
+ */
+ public KJASAppletContext( String _contextID )
+ {
+ stubs = new Hashtable();
+ images = new Hashtable();
+ pendingImages = new Vector();
+ streams = new Hashtable();
+ jsobjects = new Stack();
+ myID = _contextID;
+ active = true;
+ }
+
+ public String getID()
+ {
+ return myID;
+ }
+
+ public String getAppletID(Applet applet)
+ {
+ Enumeration e = stubs.keys();
+ while ( e.hasMoreElements() )
+ {
+ String appletID = (String) e.nextElement();
+ KJASAppletStub stub = (KJASAppletStub) stubs.get(appletID);
+ if (stub.getApplet() == applet)
+ return appletID;
+ }
+ return null;
+ }
+
+ public Applet getAppletById(String appletId) {
+ return ((KJASAppletStub) stubs.get( appletId )).getApplet();
+ }
+
+ public String getAppletName(String appletID) {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get(appletID);
+ if (stub == null)
+ return null;
+ return stub.getAppletName();
+ }
+ public void createApplet( String appletID, String name,
+ String className, String docBase,
+ String username, String password, String authname,
+ String codeBase, String archives,
+ String width, String height,
+ String windowName, Hashtable params )
+ {
+ //do kludges to support mess with parameter table and
+ //the applet variables
+ String key = new String( "ARCHIVE" );
+ if (params.containsKey(key)) {
+ String param_archive = (String)params.get(key);
+ if (archives == null) {
+ // There is no 'archive' attribute
+ // but a 'archive' param. fix archive list
+ // from param value
+ archives = param_archive;
+ } else {
+ // there is already an archive attribute.
+ // just add the value of the param to the list.
+ // But ignore bill$ personal archive format called
+ // .cab because java doesn't understand it.
+ if (!param_archive.toLowerCase().endsWith(".cab")) {
+ archives = param_archive + "," + archives;
+ }
+ }
+ } else if (archives != null) {
+ // add param if it is not present
+ params.put( key, archives);
+ }
+
+ if( codeBase == null )
+ {
+ key = new String( "CODEBASE" );
+ if( params.containsKey( key ) )
+ codeBase = (String) params.get( key );
+ }
+
+ if (username != null && !username.equals("")) {
+ try {
+ URL url = new URL(docBase);
+ int port = url.getPort();
+ if (port < 0)
+ port = url.getDefaultPort();
+ authenticator.addURL(new URL(url.getProtocol(), url.getHost(), port, ""), username, password, authname);
+ } catch (MalformedURLException muex) {
+ }
+ }
+ try
+ {
+ String sorted_archives = "";
+ TreeSet archive_set = new TreeSet();
+ if( archives != null )
+ {
+ StringTokenizer parser = new StringTokenizer( archives, ",", false );
+ while( parser.hasMoreTokens() )
+ archive_set.add ( parser.nextToken().trim() );
+ }
+ Iterator it = archive_set.iterator();
+ while (it.hasNext())
+ sorted_archives += (String) it.next();
+ KJASAppletClassLoader loader =
+ KJASAppletClassLoader.getLoader( docBase, codeBase, sorted_archives );
+ it = archive_set.iterator();
+ while (it.hasNext())
+ loader.addArchiveName( (String) it.next() );
+ loader.paramsDone();
+
+ KJASAppletStub stub = new KJASAppletStub
+ (
+ this, appletID, loader.getCodeBase(),
+ loader.getDocBase(), name, className,
+ new Dimension( Integer.parseInt(width), Integer.parseInt(height) ),
+ params, windowName, loader
+ );
+ stubs.put( appletID, stub );
+
+ stub.createApplet();
+ }
+ catch ( Exception e )
+ {
+ Main.kjas_err( "Something bad happened in createApplet: " + e, e );
+ }
+ }
+
+ public void initApplet( String appletID )
+ {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if( stub == null )
+ {
+ Main.debug( "could not init and show applet: " + appletID );
+ }
+ else
+ {
+ stub.initApplet();
+ }
+ }
+
+ public void destroyApplet( String appletID )
+ {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+
+ if( stub == null )
+ {
+ Main.debug( "could not destroy applet: " + appletID );
+ }
+ else
+ {
+ //Main.debug( "stopping applet: " + appletID );
+ stubs.remove( appletID );
+
+ stub.destroyApplet();
+ }
+ }
+
+ public void startApplet( String appletID )
+ {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if( stub == null )
+ {
+ Main.debug( "could not start applet: " + appletID );
+ }
+ else
+ {
+ stub.startApplet();
+ }
+ }
+
+ public void stopApplet( String appletID )
+ {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if( stub == null )
+ {
+ Main.debug( "could not stop applet: " + appletID );
+ }
+ else
+ {
+ stub.stopApplet();
+ }
+ }
+
+ public void destroy()
+ {
+ Enumeration e = stubs.elements();
+ while ( e.hasMoreElements() )
+ {
+ KJASAppletStub stub = (KJASAppletStub) e.nextElement();
+ stub.destroyApplet();
+ stub.loader.getJSReferencedObjects().clear();
+ }
+
+ stubs.clear();
+ active = false;
+ }
+
+ /***************************************************************************
+ **** AppletContext interface
+ ***************************************************************************/
+ public Applet getApplet( String appletName )
+ {
+ if( active )
+ {
+ Enumeration e = stubs.elements();
+ while( e.hasMoreElements() )
+ {
+ KJASAppletStub stub = (KJASAppletStub) e.nextElement();
+
+ if( stub.getAppletName().equals( appletName ) )
+ return stub.getApplet();
+ }
+ }
+
+ return null;
+ }
+
+ public Enumeration getApplets()
+ {
+ if( active )
+ {
+ Vector v = new Vector();
+ Enumeration e = stubs.elements();
+ while( e.hasMoreElements() )
+ {
+ KJASAppletStub stub = (KJASAppletStub) e.nextElement();
+ v.add( stub.getApplet() );
+ }
+
+ return v.elements();
+ }
+
+ return null;
+ }
+
+ public AudioClip getAudioClip( URL url )
+ {
+ Main.debug( "getAudioClip, url = " + url );
+ //AudioClip clip = java.applet.Applet.newAudioClip(url);
+ AudioClip clip = new KJASAudioClip(url);
+ Main.debug( "got AudioClip " + clip);
+ return clip;
+ // return new KJASSoundPlayer( myID, url );
+ }
+
+ public void addImage( String url, byte[] data )
+ {
+ Main.debug( "addImage for url = " + url );
+ images.put( url, data );
+ if (Main.cacheImages) {
+ pendingImages.remove(url);
+ }
+ }
+
+ public Image getImage( URL url )
+ {
+ if( active && url != null )
+ {
+ // directly load images using JVM
+ if (true) {
+ // Main.info("Getting image using ClassLoader:" + url);
+ if (loader != null) {
+ url = loader.findResource(url.toString());
+ //Main.debug("Resulting URL:" + url);
+ }
+ Toolkit kit = Toolkit.getDefaultToolkit();
+ Image img = kit.createImage(url);
+ return img;
+ }
+
+ //check with the Web Server
+ String str_url = url.toString();
+ Main.debug( "getImage, url = " + str_url );
+ if (Main.cacheImages && images.containsKey(str_url)) {
+ Main.debug("Cached: url=" + str_url);
+ }
+ else
+ {
+ if (Main.cacheImages) {
+ if (!pendingImages.contains(str_url)) {
+ Main.protocol.sendGetURLDataCmd( myID, str_url );
+ pendingImages.add(str_url);
+ }
+ } else {
+ Main.protocol.sendGetURLDataCmd( myID, str_url );
+ }
+ while( !images.containsKey( str_url ) && active )
+ {
+ try { Thread.sleep( 200 ); }
+ catch( InterruptedException e ){}
+ }
+ }
+ if( images.containsKey( str_url ) )
+ {
+ byte[] data = (byte[]) images.get( str_url );
+ if( data.length > 0 )
+ {
+ Toolkit kit = Toolkit.getDefaultToolkit();
+ return kit.createImage( data );
+ } else return null;
+ }
+ }
+
+ return null;
+ }
+
+ public void showDocument( URL url )
+ {
+ //Main.debug( "showDocument, url = " + url );
+
+ if( active && (url != null) )
+ {
+ Main.protocol.sendShowDocumentCmd( myID, url.toString() );
+ }
+ }
+
+ public void showDocument( URL url, String targetFrame )
+ {
+ //Main.debug( "showDocument, url = " + url + " targetFrame = " + targetFrame );
+
+ if( active && (url != null) && (targetFrame != null) )
+ {
+ Main.protocol.sendShowDocumentCmd( myID, url.toString(), targetFrame );
+ }
+ }
+
+ public void showStatus( String message )
+ {
+ if( active && (message != null) )
+ {
+ Main.protocol.sendShowStatusCmd( myID, message );
+ }
+ }
+ public boolean evaluateJavaScript(String script, String appletID, JSObject jso) {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if( active && stub != null && stub.isLoaded ()) {
+ if( jso != null ) {
+ synchronized (jsobjects) {
+ jsobjects.push(jso);
+ }
+ }
+ int [] types = { KJASAppletStub.JString };
+ String [] arglist = { script };
+ Main.protocol.sendJavaScriptEventCmd(myID, appletID, 0, "eval", types, arglist);
+ return true;
+ }
+ Main.debug( "evaluateJavaScript failure, context active:" + active + " stub:" + stub);
+ return false;
+ }
+
+ public boolean getMember(String appletID, int callid, int objid, String name)
+ {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if (stub == null || !stub.isLoaded())
+ return false;
+ return stub.getMember(callid, objid, name);
+ }
+
+ public boolean putMember(String appletID, int callid, int objid, String name, String value)
+ {
+ if (name.equals("__lc_ret")) {
+ // special case; return value of JS script evaluation
+ Main.debug("putValue: applet " + name + "=" + value);
+ JSObject jso = null;
+ synchronized (jsobjects) {
+ if (!jsobjects.empty())
+ jso = (JSObject) jsobjects.pop();
+ }
+ if (jso == null)
+ return false;
+ jso.returnvalue = value;
+ try {
+ jso.thread.interrupt();
+ } catch (SecurityException ex) {}
+ Main.protocol.sendPutMember( myID, callid, true );
+ }
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if (stub == null || !stub.isLoaded())
+ return false;
+ return stub.putMember(callid, objid, name, value);
+ }
+
+ public Object getJSReferencedObject(Applet applet, int objid)
+ {
+ return ((KJASAppletClassLoader)(applet.getClass().getClassLoader())).getJSReferencedObjects().get(new Integer(objid));
+ }
+ boolean callMember(String appletID, int cid, int oid, String n, java.util.List args)
+ {
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if (stub == null || !stub.isLoaded())
+ return false;
+ return stub.callMember( cid, oid, n, args);
+ }
+ public void derefObject(String appletID, int objid) {
+ if (objid == 0)
+ return; // that's an applet
+ KJASAppletStub stub = (KJASAppletStub) stubs.get( appletID );
+ if (stub == null)
+ return;
+ Hashtable jsRefs = stub.loader.getJSReferencedObjects();
+ if (jsRefs.remove(new Integer(objid)) == null)
+ Main.debug("couldn't remove referenced object");
+ }
+
+ public void setStream(String key, InputStream stream) throws IOException {
+ Main.debug("setStream, key = " + key);
+ streams.put(key, stream);
+ }
+ public InputStream getStream(String key){
+ Main.debug("getStream, key = " + key);
+ return (InputStream) streams.get(key);
+ }
+ public Iterator getStreamKeys() {
+ Main.debug("getStreamKeys");
+ return streams.keySet().iterator();
+ }
+
+
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASAppletPanel.java b/tdehtml/java/org/kde/kjas/server/KJASAppletPanel.java
new file mode 100644
index 000000000..d7acbdaf9
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASAppletPanel.java
@@ -0,0 +1,113 @@
+package org.kde.kjas.server;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.LayoutManager;
+import java.awt.Panel;
+import java.net.URL;
+
+/**
+ * @author till
+ *
+ * A panel which embeds the applet and shows some
+ * information during class loading.
+ */
+public class KJASAppletPanel extends javax.swing.JPanel implements StatusListener {
+ private final static int LOADING = 1;
+ private final static int RUNNING = 2;
+ private final static int FAILED = 3;
+
+ private Image load_img = null;
+ private Image fail_img = null;
+ private int status = LOADING;
+ private Font font;
+ private String msg = "Loading Applet...";
+
+ /**
+ * Constructor for KJASAppletPanel.
+ */
+ public KJASAppletPanel() {
+ super(new BorderLayout());
+ font = new Font("SansSerif", Font.PLAIN, 10);
+ URL url =
+ getClass().getClassLoader().getResource("images/animbean.gif");
+ load_img = getToolkit().createImage(url);
+ //setBackground(Color.white);
+ }
+
+ void setApplet(Applet applet) {
+ add("Center", applet);
+ validate();
+ }
+
+ public void showStatus(String msg) {
+ this.msg = msg;
+ if (status != RUNNING)
+ repaint();
+ }
+
+ public void paint(Graphics g) {
+ super.paint(g);
+ if (status == RUNNING)
+ return;
+ Image img = (status == LOADING ? load_img : fail_img);
+ int x = getWidth() / 2;
+ int y = getHeight() / 2;
+ if (img != null) {
+ //synchronized (img) {
+ int w = img.getWidth(this);
+ int h = img.getHeight(this);
+ int imgx = x - w / 2;
+ int imgy = y - h / 2;
+ //g.setClip(imgx, imgy, w, h);
+ g.drawImage(img, imgx, imgy, this);
+ y += img.getHeight(this) / 2;
+ //}
+ }
+ if (msg != null) {
+ //synchronized(msg) {
+ g.setFont(font);
+ FontMetrics m = g.getFontMetrics();
+ int h = m.getHeight();
+ int w = m.stringWidth(msg);
+ int msgx = x - w / 2;
+ int msgy = y + h;
+ //g.setClip(0, y, getWidth(), h);
+ g.drawString(msg, msgx, msgy);
+ //}
+ }
+ }
+ void showFailed() {
+ URL url =
+ getClass().getClassLoader().getResource("images/brokenbean.gif");
+ fail_img = getToolkit().createImage(url);
+ status = FAILED;
+ msg = "Applet Failed.";
+ repaint();
+ }
+
+ void showFailed(String message) {
+ showFailed();
+ showStatus(message);
+ }
+
+ public void stopAnimation() {
+ status = RUNNING;
+ }
+
+ public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
+ {
+ if (img != null && img == load_img && status != LOADING) {
+ img.flush();
+ load_img = null;
+ Main.debug("flushing image");
+ return false;
+ }
+ return super.imageUpdate(img, flags, x, y, w, h);
+ }
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASAppletStub.java b/tdehtml/java/org/kde/kjas/server/KJASAppletStub.java
new file mode 100644
index 000000000..e090183d7
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASAppletStub.java
@@ -0,0 +1,807 @@
+package org.kde.kjas.server;
+
+import java.applet.*;
+import java.util.*;
+import java.net.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.JFrame;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * The stub used by Applets to communicate with their environment.
+ *
+ */
+public final class KJASAppletStub
+ implements AppletStub
+{
+ private KJASAppletContext context; // The containing context.
+ private Hashtable params; // Maps parameter names to values
+ private URL codeBase; // The URL directory where files are
+ private URL docBase; // The document that referenced the applet
+ private boolean active; // Is the applet active?
+ private String appletName; // The name of this applet instance
+ private String appletID; // The id of this applet- for use in callbacks
+ private Dimension appletSize;
+ private String windowName;
+ private String className;
+ private Class appletClass;
+ private JFrame frame;
+
+ /**
+ * out of bounds applet state :-), perform an action
+ */
+ public static final int ACTION = -1;
+ /**
+ * applet state unknown
+ */
+ public static final int UNKNOWN = 0;
+ /**
+ * the applet class has been loaded
+ */
+ public static final int CLASS_LOADED = 1;
+ /**
+ * the applet has been instanciated
+ */
+ public static final int INSTANCIATED = 2;
+ /**
+ * the applet has been initialized
+ */
+ public static final int INITIALIZED = 3;
+ /**
+ * the applet has been started
+ */
+ public static final int STARTED = 4;
+ /**
+ * the applet has been stopped
+ */
+ public static final int STOPPED = 5;
+ /**
+ * the applet has been destroyed
+ */
+ public static final int DESTROYED = 6;
+ /**
+ * request for termination of the applet thread
+ */
+ private static final int TERMINATE = 7;
+ /**
+ * like TERMINATE, an end-point state
+ */
+ private static final int FAILED = 8;
+
+
+ //private KJASAppletClassLoader loader;
+ KJASAppletClassLoader loader;
+ private KJASAppletPanel panel;
+ private Applet app;
+ KJASAppletStub me;
+
+ /**
+ * Interface for so called LiveConnect actions, put-, get- and callMember
+ */
+ // keep this in sync with KParts::LiveConnectExtension::Type
+ private final static int JError = -1;
+ private final static int JVoid = 0;
+ private final static int JBoolean = 1;
+ private final static int JFunction = 2;
+ private final static int JNumber = 3;
+ private final static int JObject = 4;
+ final static int JString = 5;
+
+ interface AppletAction {
+ void apply();
+ void fail();
+ }
+
+ private class RunThread extends Thread {
+ private int request_state = CLASS_LOADED;
+ private int current_state = UNKNOWN;
+ private Vector actions = new Vector();
+ private AccessControlContext acc = null;
+
+ RunThread() {
+ super("KJAS-AppletStub-" + appletID + "-" + appletName);
+ setContextClassLoader(loader);
+ }
+ /**
+ * Ask applet to go to the next state
+ */
+ synchronized void requestState(int nstate) {
+ if (nstate > current_state) {
+ request_state = nstate;
+ notifyAll();
+ }
+ }
+ synchronized void requestAction(AppletAction action) {
+ actions.add(action);
+ notifyAll();
+ }
+ /**
+ * Get the asked state
+ */
+ synchronized private int getRequestState() {
+ while (request_state == current_state) {
+ if (!actions.isEmpty()) {
+ if (current_state >= INITIALIZED && current_state < STOPPED)
+ return ACTION;
+ else {
+ AppletAction action = (AppletAction) actions.remove(0);
+ action.fail();
+ }
+ } else {
+ try {
+ wait ();
+ } catch(InterruptedException ie) {
+ }
+ }
+ }
+ if (request_state == DESTROYED && current_state == STARTED)
+ return current_state + 1; // make sure we don't skip stop()
+ return request_state;
+ }
+ /**
+ * Get the current state
+ */
+ synchronized int getAppletState() {
+ return current_state;
+ }
+ /**
+ * Set the current state
+ */
+ synchronized private void setState(int nstate) {
+ current_state = nstate;
+ }
+ /**
+ * Put applet in asked state
+ * Note, kjavaapletviewer asks for create/start/stop/destroy, the
+ * missing states instance/init/terminate, we do automatically
+ */
+ private void doState(int nstate) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ switch (nstate) {
+ case CLASS_LOADED:
+ appletClass = loader.loadClass( className );
+ requestState(INSTANCIATED);
+ break;
+ case INSTANCIATED: {
+ Object object = null;
+ try {
+ object = appletClass.newInstance();
+ app = (Applet) object;
+ }
+ catch ( ClassCastException e ) {
+ if ( object != null && object instanceof java.awt.Component) {
+ app = new Applet();
+ app.setLayout(new BorderLayout());
+ app.add( (Component) object, BorderLayout.CENTER);
+ } else
+ throw e;
+ }
+ acc = new AccessControlContext(new ProtectionDomain[] {app.getClass().getProtectionDomain()});
+ requestState(INITIALIZED);
+ break;
+ }
+ case INITIALIZED:
+ app.setStub( me );
+ app.setVisible(false);
+ panel.setApplet( app );
+ if (appletSize.getWidth() > 0)
+ app.setBounds( 0, 0, appletSize.width, appletSize.height );
+ else
+ app.setBounds( 0, 0, panel.getSize().width, panel.getSize().height );
+ app.init();
+ loader.removeStatusListener(panel);
+ // stop the loading... animation
+ panel.stopAnimation();
+ app.setVisible(true);
+ break;
+ case STARTED:
+ active = true;
+ app.start();
+ frame.validate();
+ app.repaint();
+ break;
+ case STOPPED:
+ active = false;
+ app.stop();
+ if (Main.java_version > 1.399) {
+ // kill the windowClosing listener(s)
+ WindowListener[] l = frame.getWindowListeners();
+ for (int i = 0; l != null && i < l.length; i++)
+ frame.removeWindowListener(l[i]);
+ }
+ frame.setVisible(false);
+ break;
+ case DESTROYED:
+ if (app != null)
+ app.destroy();
+ frame.dispose();
+ app = null;
+ requestState(TERMINATE);
+ break;
+ default:
+ return;
+ }
+ }
+ /**
+ * RunThread run(), loop until state is TERMINATE
+ */
+ public void run() {
+ while (true) {
+ int nstate = getRequestState();
+ if (nstate >= TERMINATE)
+ return;
+ if (nstate == ACTION) {
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ AppletAction action = (AppletAction) actions.remove(0);
+ try {
+ action.apply();
+ } catch (Exception ex) {
+ Main.debug("Error during action " + ex);
+ action.fail();
+ }
+ return null;
+ }
+ },
+ acc);
+ } else { // move to nstate
+ try {
+ doState(nstate);
+ } catch (Exception ex) {
+ Main.kjas_err("Error during state " + nstate, ex);
+ if (nstate < INITIALIZED) {
+ setState(FAILED);
+ setFailed(ex.toString());
+ return;
+ }
+ } catch (Throwable tr) {
+ setState(FAILED);
+ setFailed(tr.toString());
+ return;
+ }
+ setState(nstate);
+ stateChange(nstate);
+ }
+ }
+ }
+ }
+ private RunThread runThread = null;
+
+ /**
+ * Create an AppletStub for the specified applet. The stub will be in
+ * the specified context and will automatically attach itself to the
+ * passed applet.
+ */
+ public KJASAppletStub( KJASAppletContext _context, String _appletID,
+ URL _codeBase, URL _docBase,
+ String _appletName, String _className,
+ Dimension _appletSize, Hashtable _params,
+ String _windowName, KJASAppletClassLoader _loader )
+ {
+ context = _context;
+ appletID = _appletID;
+ codeBase = _codeBase;
+ docBase = _docBase;
+ active = false;
+ appletName = _appletName;
+ className = _className.replace( '/', '.' );
+ appletSize = _appletSize;
+ params = _params;
+ windowName = _windowName;
+ loader = _loader;
+
+ String fixedClassName = _className;
+ if (_className.endsWith(".class") || _className.endsWith(".CLASS"))
+ {
+ fixedClassName = _className.substring(0, _className.length()-6);
+ }
+ else if (_className.endsWith(".java")|| _className.endsWith(".JAVA"))
+ {
+ fixedClassName = _className.substring(0, _className.length()-5);
+ }
+ className = fixedClassName.replace('/', '.');
+
+ appletClass = null;
+ me = this;
+
+
+ }
+
+ private void stateChange(int newState) {
+ Main.protocol.sendAppletStateNotification(
+ context.getID(),
+ appletID,
+ newState);
+ }
+
+ private void setFailed(String why) {
+ loader.removeStatusListener(panel);
+ panel.stopAnimation();
+ panel.showFailed();
+ Main.protocol.sendAppletFailed(context.getID(), appletID, why);
+ }
+
+ void createApplet() {
+ panel = new KJASAppletPanel();
+ frame = new JFrame(windowName);
+ // under certain circumstances, it may happen that the
+ // applet is not embedded but shown in a separate window.
+ // think of konqueror running under fvwm or gnome.
+ // than, the user should have the ability to close the window.
+
+ frame.addWindowListener
+ (
+ new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ me.destroyApplet();
+ }
+ }
+ );
+ frame.getContentPane().add( panel, BorderLayout.CENTER );
+ try {
+ if (Main.java_version > 1.399)
+ frame.setUndecorated(true);
+ } catch(java.awt.IllegalComponentStateException e) {
+ // This happens with gcj 4.0.1, ignore for now...
+ }
+ frame.setLocation( 0, 0 );
+ frame.pack();
+ // resize frame for j2sdk1.5beta1..
+ if (appletSize.getWidth() > 0)
+ frame.setBounds( 0, 0, appletSize.width, appletSize.height );
+ else
+ frame.setBounds( 0, 0, 50, 50 );
+ frame.setVisible(true);
+ loader.addStatusListener(panel);
+ runThread = new RunThread();
+ runThread.start();
+ }
+
+ /**
+ * starts the applet managed by this stub by calling the applets start() method.
+ * Also marks this stub as active.
+ * @see java.applet.Applet#start()
+ * @see java.applet.AppletStub#isActive()
+ *
+ */
+ void startApplet()
+ {
+ runThread.requestState(STARTED);
+ }
+
+ /**
+ * stops the applet managed by this stub by calling the applets stop() method.
+ * Also marks this stub as inactive.
+ * @see java.applet.Applet#stop()
+ * @see java.applet.AppletStub#isActive()
+ *
+ */
+ void stopApplet()
+ {
+ runThread.requestState(STOPPED);
+ }
+
+ /**
+ * initialize the applet managed by this stub by calling the applets init() method.
+ * @see java.applet.Applet#init()
+ */
+ void initApplet()
+ {
+ runThread.requestState(INITIALIZED);
+ }
+
+ /**
+ * destroys the applet managed by this stub by calling the applets destroy() method.
+ * Also marks the the applet as inactive.
+ * @see java.applet.Applet#init()
+ */
+ synchronized void destroyApplet()
+ {
+ runThread.requestState(DESTROYED);
+ }
+
+ static void waitForAppletThreads()
+ {
+ Thread [] ts = new Thread[Thread.activeCount() + 5];
+ int len = Thread.enumerate(ts);
+ for (int i = 0; i < len; i++) {
+ try {
+ if (ts[i].getName() != null &&
+ ts[i].getName().startsWith("KJAS-AppletStub-")) {
+ try {
+ ((RunThread) ts[i]).requestState(TERMINATE);
+ ts[i].join(10000);
+ } catch (InterruptedException ie) {}
+ }
+ } catch (Exception e) {}
+ }
+ }
+
+ /**
+ * get the Applet managed by this stub.
+ * @return the Applet or null if the applet could not be loaded
+ * or instanciated.
+ */
+ Applet getApplet()
+ {
+ if (runThread != null && runThread.getAppletState() > CLASS_LOADED)
+ return app;
+ return null;
+ }
+
+ /**
+ * get a parameter value given in the &lt;APPLET&gt; tag
+ * @param name the name of the parameter
+ * @return the value or null if no parameter with this name exists.
+ */
+
+ public String getParameter( String name )
+ {
+ return (String) params.get( name.toUpperCase() );
+ }
+
+ /**
+ * implements the isActive method of the AppletStub interface.
+ * @return if the applet managed by this stub is currently active.
+ * @see java.applet.AppletStub#isActive()
+ */
+ public boolean isActive()
+ {
+ return active;
+ }
+
+ /**
+ * determines if the applet has been loaded and instanciated
+ * and can hence be used.
+ * @return true if the applet has been completely loaded.
+ */
+ boolean isLoaded() {
+ if (runThread == null)
+ return false;
+ int state = runThread.getAppletState();
+ return (state >= INSTANCIATED && state < DESTROYED);
+ }
+
+ public void appletResize( int width, int height )
+ {
+ if( active )
+ {
+ if ( (width >= 0) && (height >= 0))
+ {
+ Main.debug( "Applet #" + appletID + ": appletResize to : (" + width + ", " + height + ")" );
+ Main.protocol.sendResizeAppletCmd( context.getID(), appletID, width, height );
+ appletSize = new Dimension( width, height );
+ //pack();
+ }
+ }
+ }
+
+ /**
+ * converts Object <b>arg</b> into an object of class <b>cl</b>.
+ * @param arg Object to convert
+ * @param cl Destination class
+ * @return An Object of the specified class with the value specified
+ * in <b>arg</b>
+ */
+ private static final Object cast(Object arg, Class cl) throws NumberFormatException {
+ Object ret = arg;
+ if (arg == null) {
+ ret = null;
+ }
+ else if (cl.isAssignableFrom(arg.getClass())) {
+ return arg;
+ }
+ else if (arg instanceof String) {
+ String s = (String)arg;
+ Main.debug("Argument String: \"" + s + "\"");
+ if (cl == Boolean.TYPE || cl == Boolean.class) {
+ ret = new Boolean(s);
+ } else if (cl == Integer.TYPE || cl == Integer.class) {
+ ret = new Integer(s);
+ } else if (cl == Long.TYPE || cl == Long.class) {
+ ret = new Long(s);
+ } else if (cl == Float.TYPE || cl == Float.class) {
+ ret = new Float(s);
+ } else if (cl == Double.TYPE || cl == Double.class) {
+ ret = new Double(s);
+ } else if (cl == Short.TYPE || cl == Short.class) {
+ ret = new Short(s);
+ } else if (cl == Byte.TYPE || cl == Byte.class) {
+ ret = new Byte(s);
+ } else if (cl == Character.TYPE || cl == Character.class) {
+ ret = new Character(s.charAt(0));
+ }
+ }
+ return ret;
+ }
+ private Method findMethod(Class c, String name, Class [] argcls) {
+ try {
+ Method[] methods = c.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method m = methods[i];
+ if (m.getName().equals(name)) {
+ Main.debug("Candidate: " + m);
+ Class [] parameterTypes = m.getParameterTypes();
+ if (argcls == null) {
+ if (parameterTypes.length == 0) {
+ return m;
+ }
+ } else {
+ if (argcls.length == parameterTypes.length) {
+ for (int j = 0; j < argcls.length; j++) {
+ // Main.debug("Parameter " + j + " " + parameterTypes[j]);
+ argcls[j] = parameterTypes[j];
+ }
+ return m;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ private int[] getJSTypeValue(Hashtable jsRefs, Object obj, int objid, StringBuffer value) {
+ String val = obj.toString();
+ int[] rettype = { JError, objid };
+ String type = obj.getClass().getName();
+ if (type.equals("boolean") || type.equals("java.lang.Boolean"))
+ rettype[0] = JBoolean;
+ else if (type.equals("int") || type.equals("long") ||
+ type.equals("float") || type.equals("double") ||
+ type.equals("byte") || obj instanceof java.lang.Number)
+ rettype[0] = JNumber;
+ else if (type.equals("java.lang.String"))
+ rettype[0] = JString;
+ else if (!type.startsWith("org.kde.kjas.server") &&
+ !(obj instanceof java.lang.Class &&
+ ((Class)obj).getName().startsWith("org.kde.kjas.server"))) {
+ rettype[0] = JObject;
+ rettype[1] = obj.hashCode();
+ jsRefs.put(new Integer(rettype[1]), obj);
+ }
+ value.insert(0, val);
+ return rettype;
+ }
+ private class PutAction implements AppletAction {
+ int call_id;
+ int objid;
+ String name;
+ String value;
+ PutAction(int cid, int oid, String n, String v) {
+ call_id = cid;
+ objid = oid;
+ name = n;
+ value = v;
+ }
+ public void apply() {
+ Hashtable jsRefs = loader.getJSReferencedObjects();
+ Object o = objid==0 ? getApplet() : jsRefs.get(new Integer(objid));
+ if (o == null) {
+ Main.debug("Error in putValue: object " + objid + " not found");
+ fail();
+ return;
+ }
+ Field f;
+ try {
+ f = o.getClass().getField(name);
+ } catch (Exception e) {
+ fail();
+ return;
+ }
+ if (f == null) {
+ Main.debug("Error in putValue: " + name + " not found");
+ fail();
+ return;
+ }
+ try {
+ String type = f.getType().getName();
+ Main.debug("putValue: (" + type + ")" + name + "=" + value);
+ if (type.equals("boolean"))
+ f.setBoolean(o, Boolean.getBoolean(value));
+ else if (type.equals("java.lang.Boolean"))
+ f.set(o, Boolean.valueOf(value));
+ else if (type.equals("int"))
+ f.setInt(o, Integer.parseInt(value));
+ else if (type.equals("java.lang.Integer"))
+ f.set(o, Integer.valueOf(value));
+ else if (type.equals("byte"))
+ f.setByte(o, Byte.parseByte(value));
+ else if (type.equals("java.lang.Byte"))
+ f.set(o, Byte.valueOf(value));
+ else if (type.equals("char"))
+ f.setChar(o, value.charAt(0));
+ else if (type.equals("java.lang.Character"))
+ f.set(o, new Character(value.charAt(0)));
+ else if (type.equals("double"))
+ f.setDouble(o, Double.parseDouble(value));
+ else if (type.equals("java.lang.Double"))
+ f.set(o, Double.valueOf(value));
+ else if (type.equals("float"))
+ f.setFloat(o, Float.parseFloat(value));
+ else if (type.equals("java.lang.Float"))
+ f.set(o, Float.valueOf(value));
+ else if (type.equals("long"))
+ f.setLong(o, Long.parseLong(value));
+ else if (type.equals("java.lang.Long"))
+ f.set(o, Long.valueOf(value));
+ else if (type.equals("short"))
+ f.setShort(o, Short.parseShort(value));
+ else if (type.equals("java.lang.Short"))
+ f.set(o, Short.valueOf(value));
+ else if (type.equals("java.lang.String"))
+ f.set(o, value);
+ else {
+ Main.debug("Error putValue: unsupported type: " + type);
+ fail();
+ return;
+ }
+ } catch (Exception e) {
+ Main.debug("Exception in putValue: " + e.getMessage());
+ fail();
+ return;
+ }
+ Main.protocol.sendPutMember( context.getID(), call_id, true );
+ }
+ public void fail() {
+ Main.protocol.sendPutMember( context.getID(), call_id, false );
+ }
+ }
+ private class GetAction implements AppletAction {
+ int call_id;
+ int objid;
+ String name;
+ GetAction(int cid, int oid, String n) {
+ call_id = cid;
+ objid = oid;
+ name = n;
+ }
+ public void apply() {
+ Main.debug("getMember: " + name);
+ StringBuffer value = new StringBuffer();
+ int ret[] = { JError, objid };
+ Hashtable jsRefs = loader.getJSReferencedObjects();
+ Object o = objid==0 ? getApplet() : jsRefs.get(new Integer(objid));
+ if (o == null) {
+ fail();
+ return;
+ }
+ Class c = o.getClass();
+ try {
+ Field field = c.getField(name);
+ ret = getJSTypeValue(jsRefs, field.get(o), objid, value);
+ } catch (Exception ex) {
+ Method [] m = c.getMethods();
+ for (int i = 0; i < m.length; i++)
+ if (m[i].getName().equals(name)) {
+ ret[0] = JFunction;
+ break;
+ }
+ }
+ Main.protocol.sendMemberValue(context.getID(), KJASProtocolHandler.GetMember, call_id, ret[0], ret[1], value.toString());
+ }
+ public void fail() {
+ Main.protocol.sendMemberValue(context.getID(), KJASProtocolHandler.GetMember, call_id, -1, 0, "");
+ }
+ }
+ private class CallAction implements AppletAction {
+ int call_id;
+ int objid;
+ String name;
+ java.util.List args;
+ CallAction(int cid, int oid, String n, java.util.List a) {
+ call_id = cid;
+ objid = oid;
+ name = n;
+ args = a;
+ }
+ public void apply() {
+ StringBuffer value = new StringBuffer();
+ Hashtable jsRefs = loader.getJSReferencedObjects();
+ int [] ret = { JError, objid };
+ Object o = objid==0 ? getApplet() : jsRefs.get(new Integer(objid));
+ if (o == null) {
+ fail();
+ return;
+ }
+
+ try {
+ Main.debug("callMember: " + name);
+ Object obj;
+ Class c = o.getClass();
+ String type;
+ Class [] argcls = new Class[args.size()];
+ for (int i = 0; i < args.size(); i++)
+ argcls[i] = name.getClass(); // String for now, will be updated by findMethod
+ Method m = findMethod(c, (String) name, argcls);
+ Main.debug("Found Method: " + m);
+ if (m != null) {
+ Object [] argobj = new Object[args.size()];
+ for (int i = 0; i < args.size(); i++) {
+ argobj[i] = cast(args.get(i), argcls[i]);
+ }
+ Object retval = m.invoke(o, argobj);
+ if (retval == null)
+ ret[0] = JVoid;
+ else
+ ret = getJSTypeValue(jsRefs, retval, objid, value);
+ }
+ } catch (Exception e) {
+ Main.debug("callMember threw exception: " + e.toString());
+ }
+ Main.protocol.sendMemberValue(context.getID(), KJASProtocolHandler.CallMember, call_id, ret[0], ret[1], value.toString());
+ }
+ public void fail() {
+ Main.protocol.sendMemberValue(context.getID(), KJASProtocolHandler.CallMember, call_id, -1, 0, "");
+ }
+ }
+ boolean putMember(int callid, int objid, String name, String val) {
+ if (runThread == null)
+ return false;
+ runThread.requestAction( new PutAction( callid, objid, name, val) );
+ return true;
+ }
+ boolean getMember(int cid, int oid, String name) {
+ if (runThread == null)
+ return false;
+ runThread.requestAction( new GetAction( cid, oid, name) );
+ return true;
+ }
+ boolean callMember(int cid, int oid, String name, java.util.List args) {
+ if (runThread == null)
+ return false;
+ runThread.requestAction( new CallAction( cid, oid, name, args) );
+ return true;
+ }
+ /*************************************************************************
+ ********************** AppletStub Interface *****************************
+ *************************************************************************/
+ /**
+ * implements the getAppletContext method of the AppletStub interface.
+ * @return the AppletContext to which this stub belongs.
+ * @see java.applet.AppletStub#getAppletContext()
+ */
+ public AppletContext getAppletContext()
+ {
+ return context;
+ }
+
+ /**
+ * implements the getCodeBase method of the AppletStub interface.
+ * @return the code base of the applet as given in the &lt;APPLET&gt; tag.
+ * @see java.applet.AppletStub#getCodeBase()
+ */
+ public URL getCodeBase()
+ {
+ return codeBase;
+ }
+
+ /**
+ * implements the getDocumentBase method of the AppletStub interface.
+ * @return the code base of the applet as given in the
+ * &lt;APPLET&gt; tag or determined by the containing page.
+ * @see java.applet.AppletStub#getDocumentBase()
+ */
+ public URL getDocumentBase()
+ {
+ return docBase;
+ }
+
+ /**
+ * get the applet's name
+ * @return the name of the applet as given in the
+ * &lt;APPLET&gt; tag or determined by the <em>code</em> parameter.
+ */
+ public String getAppletName()
+ {
+ return appletName;
+ }
+
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASAudioClip.java b/tdehtml/java/org/kde/kjas/server/KJASAudioClip.java
new file mode 100644
index 000000000..3a40cf6e0
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASAudioClip.java
@@ -0,0 +1,98 @@
+package org.kde.kjas.server;
+
+import java.applet.*;
+import java.net.*;
+import java.util.*;
+/**
+* Background Audioclip Loader and Player.
+* @author Till Krech (till@snafu.de)
+*/
+public class KJASAudioClip implements AudioClip
+{
+ private AudioClip theClip;
+ private final static int PLAYING = 1;
+ private final static int LOOPING = 2;
+ private final static int STOPPED = 3;
+ private int state;
+ private static Hashtable cache = new Hashtable();
+
+ /**
+ * creates a new Audioclip.
+ * The AudioClip is loaded in background. The Constructor returns immediately.
+ */
+ public KJASAudioClip(URL url)
+ {
+ state = STOPPED;
+ theClip = (AudioClip)cache.get(url);
+ if (theClip == null) {
+ final URL theUrl = url;
+
+ new Thread
+ (
+ new Runnable() {
+ public void run() {
+ theClip = java.applet.Applet.newAudioClip(theUrl);
+ cache.put(theUrl, theClip);
+ if (state == LOOPING) {
+ theClip.loop();
+ } else if (state == PLAYING) {
+ theClip.play();
+ }
+ }
+ }, "AudioClipLoader " + url.getFile()
+ ).start();
+ }
+ }
+
+ /**
+ * play continously when the clip is loaded
+ */
+ public void loop()
+ {
+ state = LOOPING;
+ if (theClip != null) {
+ new Thread
+ (
+ new Runnable() {
+ public void run() {
+ theClip.loop();
+ }
+ }, "AudioClipLooper "
+ ).start();
+ }
+ }
+
+ /**
+ * play when the clip is loaded
+ */
+ public void play()
+ {
+ state = PLAYING;
+ if (theClip != null) {
+ new Thread
+ (
+ new Runnable() {
+ public void run() {
+ theClip.play();
+ }
+ }, "AudioClipPlayer "
+ ).start();
+ }
+ }
+
+ /**
+ * stop the clip
+ */
+ public void stop()
+ {
+ state = STOPPED;
+ if (theClip != null) {
+ theClip.stop();
+ }
+ }
+
+ public void finalize() {
+ stop();
+ }
+}
+
diff --git a/tdehtml/java/org/kde/kjas/server/KJASBrokenClassFixer.java b/tdehtml/java/org/kde/kjas/server/KJASBrokenClassFixer.java
new file mode 100644
index 000000000..aab1be4af
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASBrokenClassFixer.java
@@ -0,0 +1,132 @@
+package org.kde.kjas.server;
+import java.lang.reflect.*;
+import java.net.URLClassLoader;
+import java.net.URL;
+/**
+* wrapper for the javaplugin.jar Broken11ClassFixer.
+* Uses the reflection api to wrap the class <i>sun.plugin.security.Broken11ClassFixer</i>
+* from the javaplugin.jar archive which can be found in the jre/lib directory.
+*/
+public class KJASBrokenClassFixer {
+ private static Class fixerClass = null;
+ private static Method _process;
+ private static Method _getProcessedData;
+ private static Method _getProcessedDataOffset;
+ private static Method _getProcessedDataLength;
+ private static boolean initialized = false;
+ private static final String fixerClassName = "sun.plugin.security.Broken11ClassFixer";
+ private Object fixer = null;
+ private byte [] bytes;
+ private int offset;
+ private int length;
+
+ /**
+ * creates a new KJASBrokenClassFixer.
+ * If it is the first one to be created, it tries to load the class
+ * <i>sun.plugin.security.Broken11ClassFixer</i> from the jar file
+ * <i>lib/javaplugin.jar</i> in the java jre directory.
+ */
+ public KJASBrokenClassFixer() {
+ init();
+ if (fixerClass != null) {
+ try {
+ fixer = fixerClass.newInstance();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * loads the class <i>sun.plugin.security.Broken11ClassFixer</i>,
+ * initializes the methods, ...
+ */
+ private synchronized void init() {
+ if (initialized) {
+ return;
+ }
+ try {
+ URL [] urls = { new URL(
+ "file", "", 0,
+ System.getProperty("java.home")
+ + System.getProperty("file.separator")
+ + "lib"
+ + System.getProperty("file.separator")
+ + "javaplugin.jar"), new URL(
+ "file", "", 0,
+ System.getProperty("java.home")
+ + System.getProperty("file.separator")
+ + "lib"
+ + System.getProperty("file.separator")
+ + "plugin.jar")
+ };
+ URLClassLoader loader = new URLClassLoader(urls);
+ fixerClass = Class.forName(fixerClassName, true, loader);
+ Main.debug("Loaded " + fixerClass);
+ final Class [] parameterTypes = {
+ (new byte[1]).getClass(),
+ Integer.TYPE,
+ Integer.TYPE
+ };
+ final Class [] noParameter = new Class[0];
+ _process = fixerClass.getMethod("process", parameterTypes);
+ _getProcessedData = fixerClass.getMethod("getProcessedData", noParameter);
+ _getProcessedDataOffset = fixerClass.getMethod("getProcessedDataOffset", noParameter);
+ _getProcessedDataLength = fixerClass.getMethod("getProcessedDataLength", noParameter);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ } finally {
+ initialized = true;
+ }
+ }
+ /**
+ * scan the broken bytes and create new ones.
+ * If the wrapped class could not be loaded or
+ * no instance of Broken11ClassFixer could be instantiated,
+ * this is a noop and later calls to getProcessedData() etc.
+ * will return the original data passed as arguments in this
+ * call.
+ */
+ public boolean process(byte [] b, int off, int len) {
+ if (fixer != null) {
+ try {
+ Object [] args = new Object[3];
+ args[0] = b;
+ args[1] = new Integer(off);
+ args[2] = new Integer(len);
+ Object [] none = new Object[0];
+
+ _process.invoke(fixer, args);
+ this.bytes = (byte[])_getProcessedData.invoke(fixer, none);
+ this.offset = ((Integer)_getProcessedDataOffset.invoke(fixer, none)).intValue();
+ this.length = ((Integer)_getProcessedDataLength.invoke(fixer, none)).intValue();
+ return true;
+ } catch (Throwable e) {
+ }
+ }
+ this.bytes = b;
+ this.offset = off;
+ this.length = len;
+ return false;
+ }
+
+ /**
+ * get the offset in the processed byte array
+ */
+ public int getProcessedDataOffset() {
+ return offset;
+ }
+ /**
+ * get the length of the processed data
+ */
+ public int getProcessedDataLength() {
+ return length;
+ }
+ /**
+ * get the processed (fixed) data
+ */
+ public byte [] getProcessedData() {
+ return bytes;
+ }
+
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASConsole.java b/tdehtml/java/org/kde/kjas/server/KJASConsole.java
new file mode 100644
index 000000000..51498b59b
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASConsole.java
@@ -0,0 +1,93 @@
+package org.kde.kjas.server;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+
+public class KJASConsole
+ extends Frame
+ implements Console
+{
+ private TextArea txt;
+
+ public KJASConsole()
+ {
+ super("Konqueror Java Console");
+
+ txt = new TextArea();
+ txt.setEditable(false);
+ txt.setBackground(Color.white);
+ txt.setForeground(Color.black);
+
+ Panel main = new Panel(new BorderLayout());
+ Panel btns = new Panel(new BorderLayout());
+
+ Button clear = new Button("Clear");
+ Button close = new Button("Close");
+
+ btns.add(clear, "West");
+ btns.add(close, "East");
+
+ main.add(txt, "Center");
+ main.add(btns, "South");
+
+ add( main );
+
+ clear.addActionListener
+ (
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ txt.setText("");
+ }
+ }
+ );
+
+ close.addActionListener
+ (
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ setVisible(false);
+ }
+ }
+ );
+
+ addWindowListener
+ (
+ new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ setVisible(false);
+ }
+ }
+ );
+
+ setSize(500, 300);
+
+ PrintStream st = new PrintStream( new KJASConsoleStream(this) );
+ System.setOut(st);
+ System.setErr(st);
+
+ System.out.println( "Java VM version: " +
+ System.getProperty("java.version") );
+ System.out.println( "Java VM vendor: " +
+ System.getProperty("java.vendor") );
+ }
+
+ public void clear() {
+ txt.setText("");
+ }
+
+ public void append(String msg) {
+ if (msg == null) {
+ return;
+ }
+ int length = msg.length();
+ synchronized(txt) {
+ //get the caret position, and then get the new position
+ int old_pos = txt.getCaretPosition();
+ txt.append(msg);
+ txt.setCaretPosition( old_pos + length );
+ }
+ }
+}
+
+
diff --git a/tdehtml/java/org/kde/kjas/server/KJASConsoleStream.java b/tdehtml/java/org/kde/kjas/server/KJASConsoleStream.java
new file mode 100644
index 000000000..2c1152ed4
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASConsoleStream.java
@@ -0,0 +1,46 @@
+package org.kde.kjas.server;
+import java.io.*;
+
+class KJASConsoleStream
+ extends OutputStream
+{
+ private Console console;
+ private FileOutputStream dbg_log;
+
+ public KJASConsoleStream(Console console)
+ {
+ this.console = console;
+
+ try
+ {
+ if( Main.log )
+ {
+ dbg_log = new FileOutputStream( "/tmp/kjas.log");
+ }
+ }
+ catch( FileNotFoundException e ) {}
+ }
+
+ public void close() {}
+ public void flush() {}
+ public void write(byte[] b) {}
+ public void write(int a) {}
+
+ // Should be enough for the console
+ public void write( byte[] bytes, int offset, int length )
+ {
+ try // Just in case
+ {
+ String msg = new String( bytes, offset, length );
+ console.append(msg);
+ if( Main.log && dbg_log != null )
+ {
+ dbg_log.write( msg.getBytes() );
+ dbg_log.flush();
+ }
+ }
+ catch(Throwable t) {}
+ }
+}
+
+
diff --git a/tdehtml/java/org/kde/kjas/server/KJASProtocolHandler.java b/tdehtml/java/org/kde/kjas/server/KJASProtocolHandler.java
new file mode 100644
index 000000000..f8b50a91d
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASProtocolHandler.java
@@ -0,0 +1,900 @@
+package org.kde.kjas.server;
+
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+import java.net.*;
+
+/**
+ * Encapsulates the KJAS protocol and manages the contexts
+ *
+ */
+public class KJASProtocolHandler
+{
+ // Command codes- always need to be synced up with
+ // what's in kjavaappletserver.cpp
+ private static final int CreateContextCode = 1;
+ private static final int DestroyContextCode = 2;
+ private static final int CreateAppletCode = 3;
+ private static final int DestroyAppletCode = 4;
+ private static final int StartAppletCode = 5;
+ private static final int StopAppletCode = 6;
+ private static final int InitAppletCode = 7;
+ private static final int ShowDocumentCode = 8;
+ private static final int ShowURLInFrameCode = 9;
+ private static final int ShowStatusCode = 10;
+ private static final int ResizeAppletCode = 11;
+ private static final int GetURLDataCode = 12;
+ private static final int URLDataCode = 13;
+ private static final int ShutdownServerCode = 14;
+ private static final int JavaScriptEvent = 15;
+ static final int GetMember = 16;
+ static final int CallMember = 17;
+ private static final int PutMember = 18;
+ private static final int DerefObject = 19;
+
+ private static final int AudioClipPlayCode = 20;
+ private static final int AudioClipLoopCode = 21;
+ private static final int AudioClipStopCode = 22;
+
+ private static final int AppletStateNotificationCode = 23;
+ private static final int AppletFailedCode = 24;
+ private static final int DataCommand = 25;
+ private static final int PutURLDataCode = 26;
+ private static final int PutDataCode = 27;
+ private static final int SecurityConfirmCode = 28;
+ private static final int ShowConsole = 29;
+
+ //Holds contexts in contextID-context pairs
+ private Hashtable contexts;
+
+ private PushbackInputStream commands; //Stream for reading in commands
+ private PrintStream signals; //Stream for writing out callbacks
+
+ //used for parsing each command as it comes in
+ private int cmd_index;
+ private final static char sep = (char) 0;
+
+ public KJASProtocolHandler( InputStream _commands,
+ OutputStream _signals )
+ {
+ commands = new PushbackInputStream( _commands );
+ signals = new PrintStream( _signals );
+ contexts = new Hashtable();
+ }
+
+ public void commandLoop()
+ {
+ try
+ {
+ while( true )
+ {
+ try
+ {
+ int cmd_length = readPaddedLength( 8 );
+ Main.debug( "PH: cmd_length = " + cmd_length );
+
+ //We need to have this while loop since we're not guaranteed to get
+ //all the bytes we want back, especially with large jars
+ byte[] cmd_data = new byte[cmd_length];
+ int total_read = 0;
+ while( total_read < cmd_length )
+ {
+ int numread = commands.read( cmd_data, total_read, cmd_length-total_read );
+ Main.debug( "PH: read in " + numread + " bytes for command" );
+ total_read += numread;
+ }
+
+ //parse the rest of the command and execute it
+ processCommand( cmd_data );
+ }
+ catch( NumberFormatException e )
+ {
+ Main.kjas_err( "Could not parse out message length", e );
+ e.printStackTrace();
+ System.exit( 1 );
+ }
+ catch( Throwable t )
+ {
+ Main.debug( "commandLoop caught a throwable, still going" );
+ t.printStackTrace();
+ }
+ }
+ }
+ catch( Exception i )
+ {
+ Main.kjas_err( "commandLoop exited on exception: ", i );
+ i.printStackTrace();
+ System.exit( 1 );
+ }
+ }
+
+ public void processCommand( byte[] command )
+ {
+ // Sanity checks
+ if ( command == null )
+ return;
+
+ //do all the parsing here and pass arguments as individual variables to the
+ //handler functions
+ int cmd_length = command.length;
+ cmd_index = 0;
+
+ int cmd_code_value = (int) command[cmd_index++];
+ if( cmd_code_value == CreateContextCode )
+ {
+ //parse out contextID- 1 argument
+ String contextID = getArg( command );
+ Main.debug( "createContext, id = " + contextID );
+
+ KJASAppletContext context = new KJASAppletContext( contextID );
+ contexts.put( contextID, context );
+ } else
+ if( cmd_code_value == DestroyContextCode )
+ {
+ //parse out contextID- 1 argument
+ String contextID = getArg( command );
+ Main.debug( "destroyContext, id = " + contextID );
+
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if( contexts != null )
+ {
+ context.destroy();
+ contexts.remove( contextID );
+ }
+ } else
+ if( cmd_code_value == CreateAppletCode )
+ {
+ //9 arguments- this order is important...
+ final String contextID = getArg( command );
+ final String appletID = getArg( command );
+ final String appletName = getArg( command );
+ final String className = getArg( command );
+ final String baseURL = getArg( command );
+ final String username = getArg( command );
+ final String password = getArg( command );
+ final String authname = getArg( command );
+ final String codeBase = getArg( command );
+ final String archives = getArg( command );
+ final String width = getArg( command );
+ final String height = getArg( command );
+ final String title = getArg( command );
+
+ //get the number of parameter pairs...
+ String str_params = getArg( command );
+ int num_params = Integer.parseInt( str_params.trim() );
+ final Hashtable params = new Hashtable();
+ for( int i = 0; i < num_params; i++ )
+ {
+ String name = getArg( command ); // note name is in uppercase
+ if( name == null )
+ name = new String();
+
+ String value = getArg( command );
+ if( value == null )
+ value = new String();
+ params.put( name, value );
+ //Main.debug( "parameter, name = " + name + ", value = " + value );
+ }
+
+ Main.debug( "createApplet, context = " + contextID + ", applet = " + appletID );
+ Main.debug( " name = " + appletName + ", classname = " + className );
+ Main.debug( " baseURL = " + baseURL + ", codeBase = " + codeBase );
+ Main.debug( " archives = " + archives + ", width = " + width +
+ ", height = " + height );
+
+ final KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if( context != null )
+ {
+ context.createApplet( appletID, appletName, className,
+ baseURL, username, password, authname,
+ codeBase, archives,
+ width, height, title, params );
+ }
+
+ } else
+ if( cmd_code_value == DestroyAppletCode )
+ {
+ //2 arguments
+ String contextID = getArg( command );
+ String appletID = getArg( command );
+ Main.debug( "destroyApplet, context = " + contextID + ", applet = " + appletID );
+
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if ( context != null )
+ context.destroyApplet( appletID );
+ } else
+ if( cmd_code_value == StartAppletCode )
+ {
+ //2 arguments
+ String contextID = getArg( command );
+ String appletID = getArg( command );
+ Main.debug( "startApplet, context = " + contextID + ", applet = " + appletID );
+
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if ( context != null )
+ context.startApplet( appletID );
+ } else
+ if( cmd_code_value == StopAppletCode )
+ {
+ //2 arguments
+ String contextID = getArg( command );
+ String appletID = getArg( command );
+ Main.debug( "stopApplet, context = " + contextID + ", applet = " + appletID );
+
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if ( context != null )
+ context.stopApplet( appletID );
+ } else
+ if( cmd_code_value == ShutdownServerCode )
+ {
+ Main.debug( "shutDownServer received" );
+ KJASAppletStub.waitForAppletThreads();
+ System.exit( 1 );
+ }
+ else
+ if( cmd_code_value == URLDataCode )
+ {
+
+ String id = getArg( command );
+ String code = getArg( command );
+ Main.debug( "KIO URLData received(" + id + ") code:" + code );
+
+ //rest of the command should be the data...
+ byte[] data = null;
+ if (cmd_length - cmd_index > 0) {
+ data = new byte[ cmd_length - cmd_index ];
+ System.arraycopy( command, cmd_index, data, 0, data.length );
+ }
+ KIOConnection.setData(id, Integer.parseInt(code), data);
+ } else
+ if (cmd_code_value == GetMember)
+ {
+ int ticketnr = Integer.parseInt( getArg( command ) );
+ String contextID = getArg( command );
+ String appletID = getArg( command );
+ int objid = Integer.parseInt( getArg( command ) );
+ String name = getArg( command );
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if ( context == null || !context.getMember(appletID, ticketnr, objid, name))
+ sendMemberValue(contextID, GetMember, ticketnr, -1, 0, "");
+ } else
+ if (cmd_code_value == PutMember)
+ {
+ int ticketnr = Integer.parseInt( getArg( command ) );
+ String contextID = getArg( command );
+ String appletID = getArg( command );
+ int objid = Integer.parseInt( getArg( command ) );
+ String name = getArg( command );
+ String value = getArg( command );
+ boolean ret = false;
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if (context == null || !context.putMember(appletID, ticketnr, objid, name, value))
+ sendPutMember(contextID, ticketnr, false);
+ } else
+ if (cmd_code_value == CallMember)
+ {
+ int ticketnr = Integer.parseInt( getArg( command ) );
+ String contextID = getArg( command );
+ String appletID = getArg( command );
+ int objid = Integer.parseInt( getArg( command ) );
+ String name = getArg( command );
+ int arg_count = Integer.parseInt( getArg( command ) );
+ java.util.List args = new java.util.Vector();
+ try { // fix getArg
+ String param = getArg(command);
+ while (arg_count-- > 0) {
+ if (param == null)
+ param = new String();
+ args.add(param);
+ param = getArg(command);
+ }
+ } catch (Exception e) {}
+
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if ( context == null || !context.callMember(appletID, ticketnr, objid, name, args))
+ Main.protocol.sendMemberValue(contextID, CallMember, ticketnr, -1, 0, "");
+ } else
+ if (cmd_code_value == DerefObject)
+ {
+ String contextID = getArg( command );
+ String appletID = getArg( command );
+ String objid = getArg( command );
+ KJASAppletContext context = (KJASAppletContext) contexts.get( contextID );
+ if ( context != null )
+ context.derefObject(appletID, Integer.parseInt(objid));
+ Main.debug( "DerefObject " + objid);
+ } else
+ if (cmd_code_value == SecurityConfirmCode)
+ {
+ String id = getArg( command );
+ String confirm = getArg( command );
+ Thread t = (Thread) KJASSecurityManager.confirmRequests.get(id);
+ Main.debug( "SecurityConfirmCode " + id + " confirm:" + confirm );
+ if (t != null) {
+ KJASSecurityManager.confirmRequests.put(id, confirm);
+ try {
+ t.interrupt();
+ } catch (SecurityException se) {}
+ }
+ } else
+ if (cmd_code_value == ShowConsole)
+ {
+ Main.console.setVisible(true);
+ }
+ else
+ {
+ throw new IllegalArgumentException( "Unknown command code" );
+ }
+ }
+
+ /**************************************************************
+ ***** Methods for talking to the applet server **************
+ **************************************************************/
+
+ /**
+ * sends get url request
+ */
+ public void sendGetURLDataCmd( String jobid, String url )
+ {
+ Main.debug( "sendGetURLCmd(" + jobid + ") url = " + url );
+ //length = length of args plus 1 for code, 2 for seps and 1 for end
+ byte [] url_bytes = url.getBytes();
+ int length = jobid.length() + url_bytes.length + 4;
+ byte [] bytes = new byte[ length + 8 ];
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) GetURLDataCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = jobid.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length );
+ index += url_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ /**
+ * sends command for get url request (stop/hold/resume) or put (stop)
+ */
+ public void sendDataCmd( String id, int cmd )
+ {
+ Main.debug( "sendDataCmd(" + id + ") command = " + cmd );
+ byte [] cmd_bytes = String.valueOf( cmd ).getBytes();
+ int length = id.length() + cmd_bytes.length + 4;
+ byte [] bytes = new byte[ length + 8 ];
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) DataCommand;
+ bytes[index++] = sep;
+
+ tmp_bytes = id.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( cmd_bytes, 0, bytes, index, cmd_bytes.length );
+ index += cmd_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+ /**
+ * sends put url request
+ */
+ public void sendPutURLDataCmd( String jobid, String url )
+ {
+ Main.debug( "sendPutURLCmd(" + jobid + ") url = " + url );
+ //length = length of args plus 1 for code, 2 for seps and 1 for end
+ byte [] url_bytes = url.getBytes();
+ int length = jobid.length() + url_bytes.length + 4;
+ byte [] bytes = new byte[ length + 8 ];
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) PutURLDataCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = jobid.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length );
+ index += url_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+ /**
+ * sends put data
+ */
+ public void sendPutData( String jobid, byte [] b, int off, int len )
+ {
+ Main.debug( "sendPutData(" + jobid + ") len = " + len );
+ //length = length of args plus 1 for code, 2 for seps and 1 for end
+ int length = jobid.length() + len + 4;
+ byte [] bytes = new byte[ length + 8 ];
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) PutDataCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = jobid.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( b, off, bytes, index, len );
+ index += len;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+ /**
+ * sends notification about the state of the applet.
+ * @see org.kde.kjas.server.KJASAppletStub for valid states
+ */
+ public void sendAppletStateNotification( String contextID, String appletID, int state )
+ {
+ Main.debug( "sendAppletStateNotification, contextID = " + contextID + ", appletID = " +
+ appletID + ", state=" + state );
+
+ byte [] state_bytes = String.valueOf( state ).getBytes();
+
+ int length = contextID.length() + appletID.length() + state_bytes.length + 5;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) AppletStateNotificationCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = appletID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( state_bytes, 0, bytes, index, state_bytes.length );
+ index += state_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ /**
+ * sends notification about applet failure.
+ * This can happen in any state.
+ * @param contextID context ID of the applet's context
+ * @param appletID ID of the applet
+ * @param errorMessage any message
+ */
+ public void sendAppletFailed ( String contextID, String appletID, String errorMessage)
+ {
+ Main.debug( "sendAppletFailed, contextID = " + contextID + ", appletID = " +
+ appletID + ", errorMessage=" + errorMessage );
+ byte [] msg_bytes = errorMessage.getBytes();
+ int length = contextID.length() + appletID.length() + msg_bytes.length + 5;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) AppletFailedCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = appletID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( msg_bytes, 0, bytes, index, msg_bytes.length );
+ index += msg_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ public void sendShowDocumentCmd( String loaderKey, String url )
+ {
+ Main.debug( "sendShowDocumentCmd from context#" + loaderKey + " url = " + url );
+
+ //length = length of args + 2 for seps + 1 for end + 1 for code
+ byte [] url_bytes = url.getBytes();
+ byte [] key_bytes = loaderKey.getBytes();
+ int length = key_bytes.length + url_bytes.length + 4;
+ byte [] bytes = new byte[ length + 8 ]; //8 for the length of this message
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) ShowDocumentCode;
+ bytes[index++] = sep;
+
+ System.arraycopy( key_bytes, 0, bytes, index, key_bytes.length );
+ index += key_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length );
+ index += url_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ public void sendShowDocumentCmd( String contextID, String url, String frame)
+ {
+ Main.debug( "sendShowDocumentCmd from context#" + contextID +
+ " url = " + url + ", frame = " + frame );
+
+ //length = length of args plus code, 3 seps, end
+ byte [] url_bytes = url.getBytes();
+ byte [] frame_bytes = frame.getBytes();
+ int length = contextID.length() + url_bytes.length + frame_bytes.length + 5;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) ShowURLInFrameCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length );
+ index += url_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( frame_bytes, 0, bytes, index, frame_bytes.length );
+ index += frame_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ public void sendShowStatusCmd( String contextID, String msg )
+ {
+ Main.debug( "sendShowStatusCmd, contextID = " + contextID + " msg = " + msg );
+
+ byte [] msg_bytes = msg.getBytes();
+ int length = contextID.length() + msg_bytes.length + 4;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ int index = 0;
+
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) ShowStatusCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( msg_bytes, 0, bytes, index, msg_bytes.length );
+ index += msg_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ public void sendResizeAppletCmd( String contextID, String appletID,
+ int width, int height )
+ {
+ Main.debug( "sendResizeAppletCmd, contextID = " + contextID + ", appletID = " +
+ appletID + ", width = " + width + ", height = " + height );
+
+ byte [] width_bytes = String.valueOf( width ).getBytes();
+ byte [] height_bytes = String.valueOf( height ).getBytes();
+
+ //length = length of args plus code, 4 seps, end
+ int length = contextID.length() + appletID.length() + width_bytes.length +
+ height_bytes.length + 6;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) ResizeAppletCode;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = appletID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( width_bytes, 0, bytes, index, width_bytes.length );
+ index += width_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( height_bytes, 0, bytes, index, height_bytes.length );
+ index += height_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+ public void sendJavaScriptEventCmd( String contextID, String appletID, int objid, String event, int [] types, String [] args )
+ {
+ Main.debug( "sendJavaScriptEventCmd, contextID = " + contextID + " event = " + event );
+ String objstr = new String("" + objid);
+ int length = contextID.length() + appletID.length() + event.length() + objstr.length() + 6;
+ byte [][][] arglist = null;
+ if (types != null) {
+ arglist = new byte[args.length][2][];
+ for (int i = 0; i < types.length; i++) {
+ arglist[i][0] = (new String("" + types[i])).getBytes();
+ arglist[i][1] = args[i].getBytes();
+ length += 2 + arglist[i][0].length + arglist[i][1].length;
+ }
+ }
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ int index = 0;
+
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) JavaScriptEvent;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = appletID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = objstr.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = event.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ if (types != null)
+ for (int i = 0; i < types.length; i++) {
+ System.arraycopy( arglist[i][0], 0, bytes, index, arglist[i][0].length );
+ index += arglist[i][0].length;
+ bytes[index++] = sep;
+ System.arraycopy( arglist[i][1], 0, bytes, index, arglist[i][1].length );
+ index += arglist[i][1].length;
+ bytes[index++] = sep;
+ }
+
+ signals.write( bytes, 0, bytes.length );
+ }
+ public void sendMemberValue( String contextID, int cmd, int ticketnr, int type, int rid, String value )
+ {
+ Main.debug( "sendMemberValue, contextID = " + contextID + " value = " + value + " type=" + type + " rid=" + rid );
+
+ String strticket = String.valueOf( ticketnr );
+ String strtype = String.valueOf( type );
+ String strobj = String.valueOf( rid );
+ byte [] value_bytes = value.getBytes();
+ int length = contextID.length() + value_bytes.length + strtype.length() + strobj.length() + strticket.length() + 7;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ int index = 0;
+
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) cmd;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = strticket.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = strtype.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ tmp_bytes = strobj.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( value_bytes, 0, bytes, index, value_bytes.length );
+ index += value_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ private void sendAudioClipCommand(String contextId, String url, int cmd) {
+ byte [] url_bytes = url.getBytes();
+ int length = contextId.length() + url_bytes.length + 4;
+ byte [] bytes = new byte[ length + 8 ];
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) cmd;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextId.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length );
+ index += url_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+
+ public void sendAudioClipPlayCommand(String contextId, String url) {
+ sendAudioClipCommand(contextId, url, AudioClipPlayCode);
+ }
+ public void sendAudioClipLoopCommand(String contextId, String url) {
+ sendAudioClipCommand(contextId, url, AudioClipLoopCode);
+ }
+ public void sendAudioClipStopCommand(String contextId, String url) {
+ sendAudioClipCommand(contextId, url, AudioClipStopCode);
+ }
+
+ public void sendPutMember( String contextID, int ticketnr, boolean success )
+ {
+ Main.debug("sendPutMember, contextID = " + contextID + " success = " + success);
+
+ byte [] ticket_bytes = String.valueOf( ticketnr ).getBytes();
+ byte [] ret_bytes = String.valueOf( success ? "1" : "0" ).getBytes();
+ int length = contextID.length() + ret_bytes.length + ticket_bytes.length + 5;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) PutMember;
+ bytes[index++] = sep;
+
+ tmp_bytes = contextID.getBytes();
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( ticket_bytes, 0, bytes, index, ticket_bytes.length );
+ index += ticket_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( ret_bytes, 0, bytes, index, ret_bytes.length );
+ index += ret_bytes.length;
+ bytes[index++] = sep;
+
+ signals.write( bytes, 0, bytes.length );
+ }
+ public void sendSecurityConfirm( String [] certs, int certsnr, String perm, String id )
+ {
+ Main.debug("sendSecurityConfirm, ID = " + id + " certsnr = " + certsnr);
+
+ byte [] id_bytes = id.getBytes();
+ byte [] perm_bytes = perm.getBytes();
+ byte [] certsnr_bytes = String.valueOf( certsnr ).getBytes();
+ int length = perm_bytes.length + id_bytes.length + certsnr_bytes.length + 5;
+ for (int i = 0; i < certsnr; i++)
+ length += certs[i].length() + 1;
+ byte [] bytes = new byte[ length + 8 ]; //for length of message
+ byte [] tmp_bytes = getPaddedLengthBytes( length );
+ int index = 0;
+
+ System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length );
+ index += tmp_bytes.length;
+ bytes[index++] = (byte) SecurityConfirmCode;
+ bytes[index++] = sep;
+
+ System.arraycopy( id_bytes, 0, bytes, index, id_bytes.length );
+ index += id_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( perm_bytes, 0, bytes, index, perm_bytes.length );
+ index += perm_bytes.length;
+ bytes[index++] = sep;
+
+ System.arraycopy( certsnr_bytes, 0, bytes, index, certsnr_bytes.length );
+ index += certsnr_bytes.length;
+ bytes[index++] = sep;
+
+ for (int i = 0; i < certsnr; i++) {
+ byte [] cert_bytes = certs[i].getBytes();
+ System.arraycopy( cert_bytes, 0, bytes, index, cert_bytes.length );
+ index += cert_bytes.length;
+ bytes[index++] = sep;
+ }
+
+ signals.write( bytes, 0, bytes.length );
+ }
+ /**************************************************************
+ ***** Utility functions for parsing commands ****************
+ **************************************************************/
+ private String getArg( byte[] command )
+ {
+ int begin = cmd_index;
+ while( 0 != ((int) command[cmd_index++]) );
+
+ if( cmd_index > (begin + 1) )
+ {
+ String rval = new String( command, begin, (cmd_index - begin - 1) );
+ return rval;
+ }
+ else
+ return null;
+ }
+
+ private byte[] getPaddedLengthBytes( int length )
+ {
+ byte[] length_bytes = String.valueOf( length ).getBytes();
+ if( length_bytes.length > 8 )
+ throw new IllegalArgumentException( "can't create string number of length = 8" );
+ byte [] bytes = { (byte) ' ', (byte) ' ', (byte) ' ', (byte) ' ',
+ (byte) ' ', (byte) ' ', (byte) ' ', (byte) ' '};
+ System.arraycopy( length_bytes, 0, bytes, 0, length_bytes.length );
+ return bytes;
+ }
+ private int readPaddedLength( int string_size )
+ throws IOException
+ {
+ //read in 8 bytes for command length- length will be sent as a padded string
+ byte[] length = new byte[string_size];
+ commands.read( length, 0, string_size );
+
+ String length_str = new String( length );
+ return Integer.parseInt( length_str.trim() );
+ }
+
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASSecurityManager.java b/tdehtml/java/org/kde/kjas/server/KJASSecurityManager.java
new file mode 100644
index 000000000..0525bba0c
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASSecurityManager.java
@@ -0,0 +1,243 @@
+package org.kde.kjas.server;
+
+import java.security.*;
+import java.security.cert.*;
+import java.net.*;
+import java.util.*;
+
+
+public class KJASSecurityManager extends SecurityManager
+{
+ static Hashtable confirmRequests = new Hashtable();
+ static int confirmId = 0;
+ Hashtable grantedPermissions = new Hashtable();
+ HashSet grantAllPermissions = new HashSet();
+ HashSet rejectAllPermissions = new HashSet();
+
+ private static final char [] base64table = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+ };
+ static String encode64( byte [] data)
+ {
+ StringBuffer buf = new StringBuffer( 4*((data.length + 2)/3) );
+ int i = 0, b1, b2, b3;
+ while (i < data.length - 2) {
+ b1 = data[i++];
+ b2 = data[i++];
+ b3 = data[i++];
+ buf.append( base64table[(b1 >>> 2) & 0x3F] );
+ buf.append( base64table[((b1 << 4) & 0x30) | ((b2 >>> 4) & 0xF)] );
+ buf.append( base64table[((b2 << 2) & 0x3C) | ((b3 >>> 6) & 0x03)] );
+ buf.append( base64table[b3 & 0x3F] );
+ }
+ if ( i < data.length ) {
+ b1 = data[i++];
+ buf.append( base64table[(b1 >>> 2) & 0x3F] );
+ if ( i < data.length ) {
+ b2 = data[i++];
+ buf.append( base64table[((b1 << 4) & 0x30) | ((b2 >>> 4) & 0xF)] );
+ buf.append( base64table[(b2 << 2) & 0x3C] );
+ } else {
+ buf.append( base64table[(b1 << 4) & 0x30] );
+ buf.append( "=" );
+ }
+ buf.append( '=' );
+ }
+ return buf.toString();
+ }
+ public KJASSecurityManager()
+ {
+ }
+ /**
+ * checks for an applets permission to access certain resources
+ * currently, only a check for SocketPermission is done, that the
+ * applet cannot connect to any other but the host, where it comes from.
+ * Anything else seems to be handled automagically
+ */
+ public void checkPermission(Permission perm) throws SecurityException, NullPointerException {
+ // ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ super.checkPermission(perm);
+ } catch (SecurityException se) {
+ // Don't annoy users with these
+ if (/*perm instanceof java.lang.RuntimePermission || */
+ perm instanceof java.awt.AWTPermission)
+ throw se;
+
+ // Collect certificates
+ HashSet signers = new HashSet();
+ Class [] cls = getClassContext();
+ for (int i = 1; i < cls.length; i++) {
+ Object[] objs = cls[i].getSigners();
+ if (objs != null && objs.length > 0) {
+ for (int j = 0; j < objs.length; j++)
+ if (objs[j] instanceof X509Certificate)
+ signers.add( ((X509Certificate) objs[j]) );
+ }
+ }
+ Main.debug("Certificates " + signers.size() + " for " + perm);
+
+ // Check granted/denied permission
+ if ( grantAllPermissions.contains(signers) )
+ return;
+ if ( rejectAllPermissions.contains(signers) )
+ throw se;
+ Permissions permissions = (Permissions) grantedPermissions.get(signers);
+ if (permissions != null && permissions.implies(perm))
+ return;
+
+ // Ok, ask user what to do
+ String [] certs = new String[signers.size()];
+ int certsnr = 0;
+ for (Iterator i = signers.iterator(); i.hasNext(); ) {
+ try {
+ certs[certsnr] = encode64( ((X509Certificate) i.next()).getEncoded() );
+ certsnr++;
+ } catch (CertificateEncodingException cee) {}
+ }
+ if (certsnr == 0)
+ throw se;
+ String id = "" + confirmId++;
+ confirmRequests.put(id, Thread.currentThread());
+ Main.protocol.sendSecurityConfirm(certs, certsnr, perm.toString(), id);
+ boolean granted = false;
+ try {
+ Thread.sleep(300000);
+ } catch (InterruptedException ie) {
+ if (((String) confirmRequests.get(id)).equals("yes")) {
+ granted = true;
+ permissions = (Permissions) grantedPermissions.get(signers);
+ if (permissions == null) {
+ permissions = new Permissions();
+ grantedPermissions.put(signers, permissions);
+ }
+ permissions.add(perm);
+ } else if (((String) confirmRequests.get(id)).equals("grant")) {
+ grantAllPermissions.add( signers );
+ granted = true;
+ } else if (((String) confirmRequests.get(id)).equals("reject")) {
+ rejectAllPermissions.add( signers );
+ } // else "no", "nossl" or "invalid"
+ } finally {
+ confirmRequests.remove(id);
+ }
+ if (!granted) {
+ Main.debug("Permission denied" + perm);
+ throw se;
+ }
+ }
+ }
+
+ // keytool -genkey -keystore mystore -alias myalias
+ // keytool -export -keystore mystore -alias myalias -file mycert
+ // keytool -printcert -file mycert
+ // keytool -import -keystore myotherstore -alias myalias -file mycert
+ // jarsigner -keystore mystore myjar.jar myalias
+ // jarsigner -verify -keystore myotherstore myjar.jar
+ //
+ // policy file (use policytool and check java.security):
+ // keystore "file:myotherstore", "JKS"
+ // grant signedBy "myalias"
+ // {
+ // permission java.io.FilePermission "<<ALL FILES>>", "read"
+ // }
+ //
+ // java code:
+ // KeyStore store = KeyStore.getInstance("JKS", "SUN");
+ public void disabled___checkPermission(Permission perm) throws SecurityException, NullPointerException
+ {
+ // does not seem to work as expected, Problems with proxy - and it seems that the default
+ // implementation already does all that well, what I wanted to do here.
+ // It is likely that this method will hence disappear soon again.
+ Object context = getSecurityContext();
+ Thread thread = Thread.currentThread();
+ if (perm instanceof SocketPermission) {
+ // check if this is a connection back to the originating host
+ // if not, fall through and call super.checkPermission
+ // this gives normally access denied
+ Main.debug("*** checkPermission " + perm + " in context=" + context + " Thread=" + thread);
+ // use the context class loader to determine if this is one
+ // of our applets
+ ClassLoader contextClassLoader = thread.getContextClassLoader();
+ Main.debug("* ClassLoader=" + contextClassLoader);
+ try {
+ // try to cast ...
+ KJASAppletClassLoader loader = (KJASAppletClassLoader)contextClassLoader;
+ // ok. cast succeeded. Now get the codebase of the loader
+ // because it contains the host name
+ URL codebase = loader.getCodeBase();
+ URL docbase = loader.getDocBase();
+ Main.debug("* Class Loader docbase=" + docbase + " codebase=" + codebase);
+ String hostname = perm.getName();
+ // extract the hostname from the permission name
+ // which is something like "some.host.domain:XX"
+ // with XX as the port number
+ int colonIdx = hostname.indexOf(':');
+ if (colonIdx > 0) {
+ // strip of the port
+ hostname = hostname.substring(0, colonIdx);
+ }
+ // Main.info("Checking " + hostname + "<->" + codebase.getHost());
+
+ if (hostsAreEqual(hostname, codebase.getHost())) {
+ // ok, host matches
+ String actions = perm.getActions();
+ // just check if listen is specified which we do not want
+ // to allow
+ if (actions != null && actions.indexOf("listen") >= 0) {
+ Main.debug("* Listen is not allowed.");
+ } else {
+ // ok, just return and throw _no_ exception
+ Main.debug("* Hostname equals. Permission granted.");
+ return;
+ }
+ } else {
+ Main.info("Host mismatch: " + perm + " != " + codebase.getHost());
+ }
+ } catch (ClassCastException e) {
+ Main.debug("* ClassLoader is not a KJASAppletClassLoader");
+ }
+ Main.debug("* Fall through to super.checkPermission()");
+ }
+ super.checkPermission(perm);
+ }
+
+ private static final boolean hostsAreEqual(String host1, String host2) {
+ if (host1 == null || host2 == null) {
+ return false;
+ }
+ if (host1.length() == 0 || host2.length() == 0) {
+ return false;
+ }
+ if (host1.equalsIgnoreCase(host2)) {
+ return true;
+ }
+
+ if ( Main.proxyHost != null && Main.proxyPort != 0) {
+ // if we use a proxy, we certainly cannot use DNS
+ return false;
+ }
+
+ InetAddress inet1=null, inet2=null;
+ try {
+ inet1 = InetAddress.getByName(host1);
+ } catch (UnknownHostException e) {
+ Main.kjas_err("Unknown host:" + host1, e);
+ return false;
+ }
+ try {
+ inet2 = InetAddress.getByName(host2);
+ } catch (UnknownHostException e) {
+ Main.kjas_err("Unknown host:" + host2, e);
+ return false;
+ }
+ if (inet1.equals(inet2)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/tdehtml/java/org/kde/kjas/server/KJASSoundPlayer.java b/tdehtml/java/org/kde/kjas/server/KJASSoundPlayer.java
new file mode 100644
index 000000000..a37c2bbd4
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASSoundPlayer.java
@@ -0,0 +1,36 @@
+package org.kde.kjas.server;
+
+import java.applet.*;
+import java.net.*;
+
+public class KJASSoundPlayer implements AudioClip
+{
+ private String file;
+ private String contextId;
+
+ public KJASSoundPlayer( String _contextId, URL _file )
+ {
+ file = _file.toString();
+ contextId = _contextId;
+ Main.debug("KJASSoundPlayer( URL '" + _file + "')");
+ }
+
+ public void loop()
+ {
+ Main.debug("KJASSoundPlayer loop() URL='" + file + "'");
+ Main.protocol.sendAudioClipLoopCommand(contextId, file);
+ }
+
+ public void play()
+ {
+ Main.debug("KJASSoundPlayer play() URL='" + file + "'");
+ Main.protocol.sendAudioClipPlayCommand(contextId, file);
+ }
+
+ public void stop()
+ {
+ Main.debug("KJASSoundPlayer stop() URL='" + file + "'");
+ Main.protocol.sendAudioClipStopCommand(contextId, file);
+ }
+}
+
diff --git a/tdehtml/java/org/kde/kjas/server/KJASSwingConsole.java b/tdehtml/java/org/kde/kjas/server/KJASSwingConsole.java
new file mode 100644
index 000000000..fedda6c48
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASSwingConsole.java
@@ -0,0 +1,325 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2002 Till
+ * Copyright (C) 2005 Koos Vriezen <koos ! vriezen () xs4all ! nl>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+package org.kde.kjas.server;
+
+import java.awt.Toolkit;
+import java.awt.Image;
+import java.awt.BorderLayout;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.Properties;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JButton;
+import javax.swing.JTextArea;
+import javax.swing.border.EmptyBorder;
+
+
+public class KJASSwingConsole implements Console {
+ private JFrame frame = null;
+ private JPanel jPanel1;
+ private JScrollPane jScrollPane1;
+ private JButton clearButton;
+ private JTextArea textField;
+ private JButton closeButton;
+ private JButton copyButton;
+ final static int NR_BUFFERS = 3;
+ final static int MAX_BUF_LENGTH = 3000;
+ private int queue_pos = 0;
+ private StringBuffer [] output_buffer = new StringBuffer[NR_BUFFERS];
+
+ private PrintStream real_stderr = new PrintStream(System.err);
+
+ /** Creates new form KJASSwingConsole */
+ public KJASSwingConsole() {
+ PrintStream st = new PrintStream( new KJASConsoleStream(this) );
+ System.setOut(st);
+ System.setErr(st);
+ }
+
+ private void initComponents() {
+ frame = new JFrame("Konqueror Java Console");
+ jPanel1 = new JPanel();
+ clearButton = new JButton();
+ closeButton = new JButton();
+ copyButton = new JButton();
+ jScrollPane1 = new JScrollPane();
+ textField = new JTextArea();
+
+ frame.setFont(new java.awt.Font("Monospaced", 0, 10));
+ frame.setName("KJAS Console");
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent evt) {
+ exitForm(evt);
+ }
+ });
+
+ jPanel1.setLayout(new BorderLayout());
+ jPanel1.setBorder(new EmptyBorder(new java.awt.Insets(1, 1, 1, 1)));
+ clearButton.setText("clear");
+ clearButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent evt) {
+ clearButtonActionPerformed(evt);
+ }
+ });
+
+ jPanel1.add(clearButton, BorderLayout.WEST);
+
+ closeButton.setText("close");
+ closeButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent evt) {
+ closeButtonActionPerformed(evt);
+ }
+ });
+
+ jPanel1.add(closeButton, BorderLayout.EAST);
+
+ copyButton.setText("copy");
+ copyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent evt) {
+ copyButtonActionPerformed(evt);
+ }
+ });
+
+ jPanel1.add(copyButton, BorderLayout.CENTER);
+
+ frame.getContentPane().add(jPanel1, BorderLayout.SOUTH);
+
+ textField.setColumns(40);
+ textField.setEditable(false);
+ textField.setRows(10);
+ textField.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ textFieldKeyPressed(evt);
+ }
+ });
+
+ jScrollPane1.setViewportView(textField);
+
+ frame.getContentPane().add(jScrollPane1, BorderLayout.CENTER);
+
+ try {
+ java.net.URL iconUrl = getClass().getClassLoader().getResource("images/beanicon.png");
+ if (iconUrl != null) {
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ Image icon = tk.createImage(iconUrl);
+ frame.setIconImage(icon);
+ }
+ } catch (Throwable e) {
+ }
+ frame.pack();
+ frame.setSize(500, 300);
+ }
+
+ private void textFieldKeyPressed(java.awt.event.KeyEvent evt) {
+ // Add your handling code here:
+ char key = evt.getKeyChar();
+ switch (key) {
+ case 'h':
+ showHelp();
+ break;
+ case 'g':
+ append("Running Garbage Collection ...\n", true);
+ System.gc();
+ case 'm':
+ append("Total Memory: " + Runtime.getRuntime().totalMemory() + " bytes\n", true);
+ append("Free Memory : " + Runtime.getRuntime().freeMemory() + " bytes\n", true);
+ break;
+ case 'c':
+ clear();
+ break;
+ case 's':
+ showSystemProperties();
+ break;
+ case 't':
+ showThreads();
+ break;
+ case 'x':
+ KJASAppletClassLoader.removeLoaders();
+ append("Emptied Classloader Cache\n", true);
+ break;
+ }
+ }
+
+ private void showHelp() {
+ append("Java VM: " + System.getProperty("java.vendor") + " " + System.getProperty("java.version") + "\n", true);
+ String ph = System.getProperty("http.proxyHost");
+ if (ph != null) {
+ append("Proxy: " + ph + ":" + System.getProperty("java.proxyPort") + "\n", true);
+ }
+ SecurityManager sec = System.getSecurityManager();
+ if (sec == null) {
+ append("WARNING: Security Manager disabled!\n", true);
+ } else {
+ append("SecurityManager=" + sec + "\n", true);
+ }
+ appendSeparator();
+ append("Konqueror Java Console Help\n", true);
+ append(" c: clear console\n", true);
+ append(" g: run garbage collection\n", true);
+ append(" h: show help\n", true);
+ append(" m: show memory info\n", true);
+ append(" s: print system properties\n", true);
+ append(" t: list threads\n", true);
+ append(" x: empty classloader cache\n", true);
+ appendSeparator();
+ }
+
+ private void showSystemProperties() {
+ append("Printing System Properties ...\n", true);
+ appendSeparator();
+ Properties p = System.getProperties();
+ for (Enumeration e = p.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ if ("line.separator".equals(key)) {
+ String value = (String) p.get(key);
+ StringBuffer unescaped = new StringBuffer(10);
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ if (c == '\n') unescaped.append("\\n");
+ else if (c == '\r') unescaped.append("\\n");
+ else unescaped.append(c);
+ }
+ append(key + " = " + unescaped + "\n", true);
+ } else append(key + " = " + p.get(key) + "\n", true);
+ }
+ appendSeparator();
+ }
+
+ private void showThreads() {
+ Thread t = Thread.currentThread();
+ ThreadGroup g = t.getThreadGroup();
+ ThreadGroup parent;
+ while ((parent = g.getParent()) != null) {
+ g = parent;
+ }
+ g.list();
+ }
+
+ private void copyButtonActionPerformed(java.awt.event.ActionEvent evt) {
+ textField.selectAll();
+ textField.copy();
+ }
+
+ private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {
+ frame.setVisible(false);
+ }
+
+ private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {
+ clear();
+ }
+
+ /** Exit the Application */
+ private void exitForm(java.awt.event.WindowEvent evt) {
+ frame.setVisible(false);
+ }
+
+ public void setVisible(boolean visible) {
+ if (frame == null && visible) {
+ initComponents();
+ frame.setVisible(visible);
+ System.out.println( "Java VM version: " +
+ System.getProperty("java.version") );
+ System.out.println( "Java VM vendor: " +
+ System.getProperty("java.vendor") );
+ String ph = System.getProperty("http.proxyHost");
+ String pp = System.getProperty("http.proxyPort");
+ if (ph != null) {
+ System.out.println("Proxy: " + ph + ":" + pp);
+ }
+ SecurityManager sec = System.getSecurityManager();
+ Main.debug("SecurityManager=" + sec);
+ if (sec == null) {
+ System.out.println( "WARNING: Security Manager disabled!" );
+ textField.setForeground(java.awt.Color.red);
+ }
+ showHelp();
+ } else if (frame != null)
+ frame.setVisible(visible);
+
+ if (visible) {
+ for (int i = 0; i < NR_BUFFERS; i++)
+ if (output_buffer[(queue_pos + i + 1) % 3] != null) {
+ textField.append(output_buffer[(queue_pos + i + 1) % 3].toString());
+ output_buffer[(queue_pos + i + 1) % 3] = null;
+ }
+ }
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ new KJASSwingConsole().setVisible(true);
+ }
+
+ public void clear() {
+ textField.setText("");
+ }
+
+ private void appendSeparator() {
+ append("----------------------------------------------------\n", true);
+ }
+
+ public void append(String txt) {
+ append(txt, false);
+ }
+
+ public void append(String txt, boolean force) {
+ if (txt == null)
+ return;
+ if (frame == null || !frame.isVisible()) {
+ if (Main.Debug)
+ real_stderr.print(txt);
+ if (output_buffer[queue_pos] != null &&
+ output_buffer[queue_pos].length() > MAX_BUF_LENGTH) {
+ queue_pos = (++queue_pos) % NR_BUFFERS;
+ if (output_buffer[queue_pos] != null) {
+ // starting overwriting old log, clear textField if exists
+ if (frame != null)
+ textField.setText("");
+ output_buffer[queue_pos] = null;
+ }
+ }
+ if (output_buffer[queue_pos] == null)
+ output_buffer[queue_pos] = new StringBuffer(txt);
+ else
+ output_buffer[queue_pos].append(txt);
+ return;
+ }
+ int length = txt.length();
+ synchronized(textField) {
+ //get the caret position, and then get the new position
+ int old_pos = textField.getCaretPosition();
+ textField.append(txt);
+ textField.setCaretPosition( old_pos + length );
+ }
+ }
+}
+
diff --git a/tdehtml/java/org/kde/kjas/server/KJASURLStreamHandlerFactory.java b/tdehtml/java/org/kde/kjas/server/KJASURLStreamHandlerFactory.java
new file mode 100644
index 000000000..58c5ff518
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/KJASURLStreamHandlerFactory.java
@@ -0,0 +1,609 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2003 Koos Vriezen <koos ! vriezen () xs4all ! nl>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+package org.kde.kjas.server;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+/**
+ *
+ */
+
+class KIOConnection
+{
+ final static int NOT_CONNECTED = 0;
+ final static int CONNECT_WAIT = 1;
+ final static int CONNECTED = 2;
+
+ final static int DATA = 0;
+ final static int FINISHED = 1;
+ final static int ERRORCODE = 2;
+ final static int CONNECT = 6;
+ final static int REQUESTDATA = 7;
+
+ final static int STOP = 0;
+ final static int HOLD = 1;
+ final static int RESUME = 2;
+
+ protected static int id = 0;
+ static Hashtable jobs = new Hashtable(); // should be thread safe
+
+ static void setData(String jobid, int code, byte [] data) {
+ KIOConnection job = (KIOConnection) jobs.get(jobid);
+ if (job == null || !job.setData(code, data))
+ Main.info("KIO KJASHttpURLConnection gone (timedout/closed)");
+ else
+ Thread.yield();
+ }
+
+ private class KJASOutputStream extends OutputStream {
+ KJASOutputStream() {
+ }
+ public void write(int b) throws IOException {
+ byte[] buf = {(byte)b};
+ write(buf);
+ }
+ public synchronized void write(byte b[], int off, int len) throws IOException {
+ byte[] buf = new byte[len];
+ System.arraycopy(b, off, buf, 0, len);
+ sendData(buf, false);
+ }
+ public void write(byte b[]) throws IOException {
+ write(b, 0, b.length);
+ }
+ public void close() throws IOException {
+ disconnect();
+ }
+ public void flush() throws IOException {
+ checkConnected();
+ sendData(null, true);
+ }
+ }
+
+ private class KJASInputStream extends InputStream {
+
+ KJASInputStream() {
+ }
+ public int read() throws IOException {
+ if (getData(true))
+ return 0x00ff & in_buf[in_bufpos++];
+ return -1;
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ int total = 0;
+ do {
+ if (!getData(true)) break;
+ int nr = in_buf.length - in_bufpos;
+ if (nr > len)
+ nr = len;
+ System.arraycopy(in_buf, in_bufpos, b, off, nr);
+ len -= nr;
+ total += nr;
+ off += nr;
+ in_bufpos += nr;
+ } while (len > 0);
+ return total > 0 ? total : -1;
+ }
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+ public int available() throws IOException {
+ return inAvailable();
+ }
+ public boolean markSupported() {
+ return false;
+ }
+ public void close() throws IOException {
+ disconnect();
+ }
+ }
+
+ protected URL url;
+ protected int connect_status = 0;
+ protected String jobid = null; // connection id with KIO
+ protected LinkedList data = new LinkedList(); // not thread safe
+ protected int errorcode = 0;
+ protected boolean finished = false; // all data has arived
+ protected boolean onhold = false; // KIO job is suspended
+ protected boolean request_data = false; // need data for put job
+ private KJASOutputStream out = null;
+ private KJASInputStream in = null;
+ private byte [] in_buf = null; // current input buffer
+ private int in_bufpos = 0; // position in buffer
+ private boolean in_eof = false; // all data is read
+ private final static int LOW_BUFFER_LIMIT = 5; // put onhold off
+ private final static int HIGH_BUFFER_LIMIT = 10; // put onhold on
+
+ protected KIOConnection(URL u) {
+ url = u;
+ }
+ protected void checkConnected() throws IOException {
+ if (connect_status != CONNECTED)
+ throw new IOException("not connected");
+ }
+ protected boolean haveError() {
+ return errorcode != 0;
+ }
+ synchronized protected boolean setData(int code, byte [] d) {
+ // is job still there when entering the monitor
+ if (jobs.get(jobid) == null)
+ return false;
+ if (connect_status == CONNECT_WAIT)
+ connect_status = CONNECTED;
+ switch (code) {
+ case FINISHED:
+ if (d != null && d.length > 0)
+ data.addLast(d);
+ finished = true;
+ onhold = false;
+ jobs.remove(jobid);
+ Main.debug ("KIO FINISHED (" + jobid + ") " + data.size());
+ break;
+ case DATA:
+ if (d.length > 0)
+ data.addLast(d);
+ // Main.debug ("KIO DATA (" + jobid + ") " + data.size());
+ if (!onhold && data.size() > HIGH_BUFFER_LIMIT) {
+ Main.protocol.sendDataCmd(jobid, HOLD);
+ onhold = true;
+ }
+ break;
+ case ERRORCODE:
+ String codestr = new String(d);
+ errorcode = Integer.parseInt(codestr);
+ Main.debug ("KIO ERRORECODE(" + jobid + ") " + errorcode);
+ break;
+ case CONNECT:
+ Main.debug ("KIO CONNECT(" + jobid + ") ");
+ request_data = true;
+ errorcode = 0;
+ break;
+ case REQUESTDATA:
+ Main.debug ("KIO REQUESTDATA(" + jobid + ") ");
+ request_data = true;
+ break;
+ }
+ notifyAll();
+ return true;
+ }
+
+ private synchronized boolean getData(boolean mayblock) throws IOException {
+ if (haveError()) {
+ //disconnect();
+ in_eof = true;
+ //throw new IOException("i/o error " + errorcode);
+ }
+ if (in_eof)
+ return false;
+ checkConnected();
+ if (in_buf != null && in_bufpos < in_buf.length)
+ return true;
+ int datasize = data.size();
+ if (datasize > 0) {
+ in_buf = (byte []) data.removeFirst();
+ in_bufpos = 0;
+ }
+ if (onhold && datasize < LOW_BUFFER_LIMIT) {
+ Main.protocol.sendDataCmd(jobid, RESUME);
+ onhold = false;
+ }
+ if (datasize > 0)
+ return true;
+ if (finished) {
+ in_eof = true;
+ return false;
+ }
+ if (!mayblock)
+ return false;
+ try {
+ wait();
+ } catch (InterruptedException ie) {
+ return false;
+ }
+ return getData(false);
+ }
+ synchronized private int inAvailable() throws IOException {
+ if (in_eof)
+ return 0;
+ checkConnected();
+ if (!getData(false))
+ return 0;
+ int total = in_buf.length - in_bufpos;
+ ListIterator it = data.listIterator(0);
+ while (it.hasNext())
+ total += ((byte []) it.next()).length;
+ return total;
+ }
+ synchronized private void sendData(byte [] d, boolean force) throws IOException {
+ Main.debug ("KIO sendData(" + jobid + ") force:" + force + " request_data:" + request_data);
+ if (d != null)
+ data.addLast(d);
+ if (!request_data && !force) return;
+ if (data.size() == 0) return;
+ if (force && !request_data) {
+ try {
+ wait(10000);
+ } catch (InterruptedException ie) {
+ return;
+ }
+ if (!request_data) {
+ Main.debug ("KIO sendData(" + jobid + ") timeout");
+ data.clear();
+ disconnect();
+ throw new IOException("timeout");
+ }
+ }
+ byte[] buf;
+ int total = 0;
+ ListIterator it = data.listIterator(0);
+ while (it.hasNext())
+ total += ((byte []) it.next()).length;
+ buf = new byte[total];
+ int off = 0;
+ it = data.listIterator(0);
+ while (it.hasNext()) {
+ byte [] b = (byte []) it.next();
+ System.arraycopy(b, 0, buf, off, b.length);
+ off += b.length;
+ }
+ data.clear();
+ request_data = false;
+ Main.protocol.sendPutData(jobid, buf, 0, total);
+ }
+ synchronized void connect(boolean doInput) throws IOException {
+ if (connect_status == CONNECTED)
+ return; // javadocs: call is ignored
+ //(new Exception()).printStackTrace();
+ Main.debug ("KIO connect " + url);
+ errorcode = 0;
+ finished = in_eof = false;
+ jobid = String.valueOf(id++);
+ jobs.put(jobid, this);
+ if (doInput)
+ Main.protocol.sendGetURLDataCmd(jobid, url.toExternalForm());
+ else
+ Main.protocol.sendPutURLDataCmd(jobid, url.toExternalForm());
+ connect_status = CONNECT_WAIT;
+ try {
+ wait(20000);
+ } catch (InterruptedException ie) {
+ errorcode = -1;
+ }
+ boolean isconnected = (connect_status == CONNECTED);
+ if (isconnected && !haveError()) {
+ if (doInput)
+ in = new KJASInputStream();
+ else
+ out = new KJASOutputStream();
+ Main.debug ("KIO connect(" + jobid + ") " + url);
+ return;
+ }
+ connect_status = NOT_CONNECTED;
+ jobs.remove(jobid);
+ if (isconnected) {
+ if (!finished)
+ Main.protocol.sendDataCmd(jobid, STOP);
+ Main.debug ("KIO connect error " + url);
+ throw new ConnectException("connection failed (not found)");
+ }
+ Main.debug ("KIO connect timeout " + url);
+ throw new IOException("connection failed (timeout)");
+ }
+ synchronized void disconnect() {
+ if (connect_status == NOT_CONNECTED)
+ return;
+ Main.debug ("KIO disconnect " + jobid);
+ //(new Exception()).printStackTrace();
+ if (out != null) {
+ try {
+ out.flush();
+ } catch (IOException iox) {}
+ }
+ connect_status = NOT_CONNECTED;
+ out = null;
+ in = null;
+ if (!finished) {
+ Main.protocol.sendDataCmd(jobid, STOP);
+ jobs.remove(jobid);
+ }
+ notifyAll();
+ }
+ InputStream getInputStream() throws IOException {
+ Main.debug ("KIO getInputStream(" + jobid + ") " + url);
+ return in;
+ }
+ OutputStream getOutputStream() throws IOException {
+ Main.debug ("KIO getOutputStream(" + jobid + ") " + url);
+ return out;
+ }
+}
+
+final class KIOHttpConnection extends KIOConnection
+{
+ final static int HEADERS = 3;
+ final static int REDIRECT = 4;
+ final static int MIMETYPE = 5;
+
+ Vector headers = new Vector();
+ Hashtable headersmap = new Hashtable();
+ String responseMessage = null;
+ int responseCode = -1;
+
+ KIOHttpConnection(URL u) {
+ super(u);
+ }
+ protected boolean haveError() {
+ return super.haveError() ||
+ responseCode != 404 && (responseCode < 0 || responseCode >= 400);
+ }
+ protected synchronized boolean setData(int code, byte [] d) {
+ switch (code) {
+ case HEADERS:
+ StringTokenizer tokenizer = new StringTokenizer(new String(d), "\n");
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ int pos = token.indexOf(":");
+ String [] entry = {
+ token.substring(0, pos > -1 ? pos : token.length()).toLowerCase(), token.substring(pos > -1 ? pos+1: token.length()).trim()
+ };
+ headers.add(entry);
+ headersmap.put(entry[0], entry[1]);
+ // Main.debug ("KIO header " + entry[0] + "=" + entry[1]);
+ }
+ responseCode = 0;
+ if (headersmap.size() > 0) {
+ String token = ((String []) headers.get(0))[0];
+ if (!token.startsWith("http/1.")) break;
+ int spos = token.indexOf(' ');
+ if (spos < 0) break;
+ int epos = token.indexOf(' ', spos + 1);
+ if (epos < 0) break;
+ responseCode = Integer.parseInt(token.substring(spos+1, epos));
+ responseMessage = token.substring(epos+1);
+ Main.debug ("KIO responsecode=" + responseCode);
+ }
+ break;
+ }
+ return super.setData(code, d);
+ }
+}
+
+final class KIOSimpleConnection extends KIOConnection
+{
+ KIOSimpleConnection(URL u) {
+ super(u);
+ }
+}
+
+final class KJASHttpURLConnection extends HttpURLConnection
+{
+ private KIOHttpConnection kioconnection;
+
+ KJASHttpURLConnection(URL u) {
+ super(u);
+ kioconnection = new KIOHttpConnection(u);
+ }
+ public Map getHeaderFields() {
+ try {
+ connect();
+ } catch (IOException e) {
+ Main.debug ("Error on implicit connect()");
+ }
+ Main.debug ("KIO getHeaderFields");
+ return kioconnection.headersmap;
+ }
+ public String getHeaderField(String name) {
+ try {
+ connect();
+ } catch (IOException e) {
+ Main.debug ("Error on implicit connect()");
+ }
+ String field = (String) kioconnection.headersmap.get(name);
+ Main.debug ("KIO getHeaderField:" + name + "=" + field);
+ //(new Exception()).printStackTrace();
+ return field;
+ }
+ public String getHeaderField(int n) {
+ try {
+ connect();
+ } catch (IOException e) {
+ Main.debug ("Error on implicit connect()");
+ }
+ Main.debug ("KIO getHeaderField(" + n + ") size=" + kioconnection.headersmap.size());
+ if (n >= kioconnection.headersmap.size())
+ return null;
+ String [] entry = (String []) kioconnection.headers.get(n);
+ String line = entry[0];
+ if (entry[1].length() > 0)
+ line += ":" + entry[1];
+ Main.debug ("KIO getHeaderField(" + n + ")=#" + line + "#");
+ return line;
+ }
+ public String getHeaderFieldKey(int n) {
+ try {
+ connect();
+ } catch (IOException e) {
+ Main.debug ("Error on implicit connect()");
+ }
+ Main.debug ("KIO getHeaderFieldKey " + n);
+ if (n >= kioconnection.headersmap.size())
+ return null;
+ return ((String []) kioconnection.headers.get(n))[0];
+ }
+ public int getResponseCode() throws IOException {
+ Main.debug ("KIO getResponseCode");
+ if (kioconnection.responseCode == -1) {
+ try {
+ connect();
+ } catch (IOException e) {
+ if (kioconnection.responseCode == -1)
+ throw e;
+ }
+ }
+ responseMessage = kioconnection.responseMessage;
+ return kioconnection.responseCode;
+ }
+ public boolean usingProxy() {
+ return false; // FIXME
+ }
+ public void connect() throws IOException {
+ if (connected)
+ return;
+ Main.debug ("KIO KJASHttpURLConnection.connect " + url);
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkPermission(getPermission());
+ kioconnection.connect(doInput);
+ connected = true;
+ if (kioconnection.responseCode == 404)
+ throw new FileNotFoundException(url.toExternalForm());
+ }
+ public void disconnect() {
+ kioconnection.disconnect();
+ connected = false;
+ }
+ public InputStream getInputStream() throws IOException {
+ doInput = true;
+ doOutput = false;
+ connect();
+ return kioconnection.getInputStream();
+ }
+ public OutputStream getOutputStream() throws IOException {
+ doInput = false;
+ doOutput = true;
+ connect();
+ return kioconnection.getOutputStream();
+ }
+ public InputStream getErrorStream() {
+ Main.debug("KIO KJASHttpURLConnection.getErrorStream" + url);
+ try {
+ if (connected && kioconnection.responseCode == 404)
+ return kioconnection.getInputStream();
+ } catch (Exception ex) {}
+ return null;
+ }
+}
+
+final class KJASSimpleURLConnection extends URLConnection
+{
+ private KIOSimpleConnection kioconnection = null;
+ private int default_port;
+
+ KJASSimpleURLConnection(URL u, int p) {
+ super(u);
+ default_port = p;
+ }
+ public boolean usingProxy() {
+ return false; // FIXME
+ }
+ public Permission getPermission() throws IOException {
+ int p = url.getPort();
+ if (p < 0)
+ p = default_port;
+ return new SocketPermission(url.getHost() + ":" + p, "connect");
+ }
+ public void connect() throws IOException {
+ if (kioconnection != null)
+ return;
+ Main.debug ("KIO KJASSimpleURLConnection.connection " + url);
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkPermission(getPermission());
+ kioconnection = new KIOSimpleConnection(url);
+ kioconnection.connect(doInput);
+ connected = true;
+ }
+ public void disconnect() {
+ if (kioconnection == null)
+ return;
+ kioconnection.disconnect();
+ kioconnection = null;
+ connected = false;
+ }
+ public InputStream getInputStream() throws IOException {
+ doInput = true;
+ doOutput = false;
+ if (kioconnection == null)
+ connect();
+ return kioconnection.getInputStream();
+ }
+ public OutputStream getOutputStream() throws IOException {
+ doInput = false;
+ doOutput = true;
+ if (kioconnection == null)
+ connect();
+ return kioconnection.getOutputStream();
+ }
+}
+
+
+final class KJASHttpURLStreamHandler extends URLStreamHandler
+{
+ KJASHttpURLStreamHandler(int port) {
+ default_port = port;
+ }
+ protected URLConnection openConnection(URL u) throws IOException {
+ URL url = new URL(u.toExternalForm());
+ return new KJASHttpURLConnection(url);
+ }
+ protected int getDefaultPort() {
+ return default_port;
+ }
+ private int default_port;
+}
+
+final class KJASSimpleURLStreamHandler extends URLStreamHandler
+{
+ KJASSimpleURLStreamHandler(int port) {
+ default_port = port;
+ }
+ protected URLConnection openConnection(URL u) throws IOException {
+ URL url = new URL(u.toExternalForm());
+ return new KJASSimpleURLConnection(url, default_port);
+ }
+ protected int getDefaultPort() {
+ return default_port;
+ }
+ private int default_port;
+}
+
+public final class KJASURLStreamHandlerFactory
+ implements URLStreamHandlerFactory
+{
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ if (protocol.equals("jar") || protocol.equals("file"))
+ return null;
+ //outputs to early: Main.debug ("createURLStreamHandler " + protocol);
+ Main.debug ("KIO createURLStreamHandler " + protocol);
+ if (protocol.equals("http"))
+ return new KJASHttpURLStreamHandler(80);
+ else if (protocol.equals("https"))
+ return new KJASHttpURLStreamHandler(443);
+ else if (protocol.equals("ftp"))
+ return new KJASSimpleURLStreamHandler(21);
+ else if (protocol.equals("smb"))
+ return new KJASSimpleURLStreamHandler(139);
+ else if (protocol.equals("fish"))
+ return new KJASSimpleURLStreamHandler(22);
+ return null;
+ }
+}
diff --git a/tdehtml/java/org/kde/kjas/server/Main.java b/tdehtml/java/org/kde/kjas/server/Main.java
new file mode 100644
index 000000000..50ccb14f1
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/Main.java
@@ -0,0 +1,178 @@
+package org.kde.kjas.server;
+
+import java.io.*;
+import java.security.*;
+import java.net.*;
+
+/**
+ * KJAS server recognizes these variablers:
+ * kjas.debug - makes server actions verbose
+ * kjas.showConsole - shows Java Console window
+ * kjas.log - save a transcript of the debug output to /tmp/kjas.log
+ */
+
+public class Main
+{
+ //We need to save a reference to the original stdout
+ //for sending messages back
+ static final KJASProtocolHandler protocol;
+ static Console console = null;
+ private static final boolean show_console;
+ public static final boolean Debug;
+ public static final boolean log;
+ static final boolean cacheImages;
+ static float java_version = (float) 0.0;
+ static String proxyHost = null;
+ static int proxyPort = 0;
+ private static boolean good_jdk = true;
+
+ /**************************************************************************
+ * Initialization
+ **************************************************************************/
+ static
+ {
+ Debug = System.getProperty( "kjas.debug" ) != null;
+
+ show_console = System.getProperty( "kjas.showConsole" ) != null;
+
+ if( System.getProperty( "kjas.useKio" ) != null )
+ URL.setURLStreamHandlerFactory( new KJASURLStreamHandlerFactory() );
+
+ log = System.getProperty( "kjas.log" ) != null;
+
+ cacheImages = System.getProperty( "kjas.noImageCache" ) != null;
+
+ // determine system proxy
+ proxyHost = System.getProperty( "http.proxyHost" );
+ String proxyPortString = System.getProperty( "http.proxyPort" );
+ try {
+ proxyPort = Integer.parseInt(proxyPortString);
+ } catch (Exception e) {
+ }
+ //Main.debug( "JVM version = " + System.getProperty( "java.version" ) );
+ String version = System.getProperty("java.version").substring( 0, 3 );
+ // Hack for SGI Java2 runtime
+ if (version == "Jav") { // Skip over JavaVM- (the first 7 chars)
+ version = System.getProperty("java.version").substring(7,3);
+ }
+ //Main.debug( "JVM numerical version = " + version );
+ try {
+ java_version = Float.parseFloat( version );
+ if( java_version < 1.2 )
+ good_jdk = false;
+ } catch( NumberFormatException e ) {
+ good_jdk = false;
+ }
+ PrintStream protocol_stdout = System.out;
+ console = new KJASSwingConsole();
+ protocol = new KJASProtocolHandler( System.in, protocol_stdout );
+ }
+
+ /**************************************************************************
+ * Public Utility functions available to the KJAS framework
+ **************************************************************************/
+ public static void debug( String msg )
+ {
+ if( Debug )
+ {
+ System.out.println( "KJAS: " + msg );
+ }
+ }
+ public static void info (String msg ) {
+ System.err.println( "KJAS: " + msg );
+ }
+
+ public static void kjas_err( String msg, Exception e )
+ {
+ System.err.println( msg );
+ System.err.println( "Backtrace: " );
+ e.printStackTrace();
+ }
+
+ public static void kjas_err( String msg, Throwable t )
+ {
+ System.err.println( msg );
+ t.printStackTrace();
+ }
+ private Main() {
+ }
+
+ /**************************************************************************
+ * Main- create the command loop
+ **************************************************************************/
+ public static void main( String[] args )
+ {
+ if( !good_jdk )
+ {
+ console.setVisible( true );
+ System.err.println( "ERROR: This version of Java is not supported for security reasons." );
+ System.err.println( "\t\tPlease use Java version 1.2 or higher." );
+ return;
+ }
+
+ if( show_console )
+ console.setVisible( true );
+
+ // set up https
+ boolean hasHTTPS = true;
+
+ try {
+ // https needs a secure socket provider
+ Provider[] sslProviders = Security.getProviders("SSLContext.SSL");
+
+ if (sslProviders == null || sslProviders.length == 0) {
+ // as a fallback, try to dynamically install Sun's jsse
+ Class provider = Class.forName("com.sun.net.ssl.internal.ssl.Provider");
+
+ if (provider != null) {
+ Main.debug("adding Security Provider");
+ Provider p = (Provider) provider.newInstance();
+ Security.addProvider(p);
+ } else {
+ // Try jessie (http://www.nongnu.org/jessie/) as a fallback
+ // available in the Free World
+ provider = Class.forName("org.metastatic.jessie.provider.Jessie");
+ if (provider != null) {
+ Main.debug("adding Jessie as Security Provider");
+ Provider p = (Provider) provider.newInstance();
+ Security.addProvider(p);
+ } else {
+ Main.debug("could not get class: com.sun.net.ssl.internal.ssl.Provider");
+ hasHTTPS = false;
+ }
+ }
+ }
+
+ if (hasHTTPS) {
+ // allow user to provide own protocol handler
+ // -Djava.protocol.handler.pkgs = user.package.name
+ // getting and setting of properties might generate SecurityExceptions
+ // so this needs to be in a try block
+ String handlerPkgs = System.getProperty("java.protocol.handler.pkgs");
+
+ if (handlerPkgs == null) {
+ // set default packages for Sun and IBM
+ handlerPkgs = "com.sun.net.ssl.internal.www.protocol" +
+ "|com.ibm.net.ssl.www.protocol";
+ } else {
+ // add default packages for Sun and IBM as fallback
+ handlerPkgs += "|com.sun.net.ssl.internal.www.protocol" +
+ "|com.ibm.net.ssl.www.protocol";
+ }
+
+ System.setProperty("java.protocol.handler.pkgs", handlerPkgs);
+ }
+ } catch (Exception e) {
+ hasHTTPS = false;
+ }
+
+ if (hasHTTPS == false) {
+ System.out.println("Unable to load JSSE SSL stream handler, https support not available");
+ System.out.println("For more information see http://java.sun.com/products/jsse/");
+ }
+
+ //start the command parsing
+ protocol.commandLoop();
+ }
+
+}
diff --git a/tdehtml/java/org/kde/kjas/server/StatusListener.java b/tdehtml/java/org/kde/kjas/server/StatusListener.java
new file mode 100644
index 000000000..be17c2b29
--- /dev/null
+++ b/tdehtml/java/org/kde/kjas/server/StatusListener.java
@@ -0,0 +1,5 @@
+package org.kde.kjas.server;
+
+public interface StatusListener {
+ public void showStatus(String message);
+} \ No newline at end of file