don't discard iframe children.
[kdelibs.git] / khtml / java / kjavaprocess.cpp
blobae06579e61d2675559acb973e0d1ca9995eeefba
1 /* This file is part of the KDE project
3 * Copyright (C) 2000 Richard Moore <rich@kde.org>
4 * 2000 Wynn Wilkes <wynnw@caldera.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include "kjavaprocess.h"
24 #include <kdebug.h>
25 #include <kshell.h>
26 #include <kio/kprotocolmanager.h>
28 #include <QtCore/QTextStream>
29 #include <QtCore/QMap>
31 #include <config.h>
33 class KJavaProcessPrivate
35 friend class KJavaProcess;
36 private:
37 QString jvmPath;
38 QString classPath;
39 QString mainClass;
40 QString extraArgs;
41 QString classArgs;
42 QMap<QString, QString> systemProps;
45 KJavaProcess::KJavaProcess( QObject* parent )
46 : KProcess( parent ),
47 d(new KJavaProcessPrivate)
50 connect( this, SIGNAL( readyReadStandardOutput() ),
51 this, SLOT( slotReceivedData() ) );
52 connect( this, SIGNAL( finished( int, QProcess::ExitStatus ) ),
53 this, SLOT( slotExited() ) );
54 connect( this, SIGNAL( error( QProcess::ProcessError ) ),
55 this, SLOT( slotExited() ) );
57 d->jvmPath = "java";
58 d->mainClass = "-help";
61 KJavaProcess::~KJavaProcess()
63 if ( state() != NotRunning )
65 kDebug(6100) << "stopping java process";
66 stopJava();
68 delete d;
71 bool KJavaProcess::isRunning()
73 return state() != NotRunning;
76 bool KJavaProcess::startJava()
78 return invokeJVM();
81 void KJavaProcess::stopJava()
83 killJVM();
86 void KJavaProcess::setJVMPath( const QString& path )
88 d->jvmPath = path;
91 void KJavaProcess::setClasspath( const QString& classpath )
93 d->classPath = classpath;
96 void KJavaProcess::setSystemProperty( const QString& name,
97 const QString& value )
99 d->systemProps.insert( name, value );
102 void KJavaProcess::setMainClass( const QString& className )
104 d->mainClass = className;
107 void KJavaProcess::setExtraArgs( const QString& args )
109 d->extraArgs = args;
112 void KJavaProcess::setClassArgs( const QString& args )
114 d->classArgs = args;
117 //Private Utility Functions used by the two send() methods
118 QByteArray KJavaProcess::addArgs( char cmd_code, const QStringList& args )
120 //the buffer to store stuff, etc.
121 QByteArray buff;
122 QTextStream output( &buff, QIODevice::ReadWrite );
123 const char sep = 0;
125 //make space for the command size: 8 characters...
126 const QByteArray space( " " );
127 output << space;
129 //write command code
130 output << cmd_code;
132 //store the arguments...
133 if( args.isEmpty() )
135 output << sep;
137 else
139 QStringList::ConstIterator it = args.begin();
140 const QStringList::ConstIterator itEnd = args.end();
141 for( ; it != itEnd; ++it )
143 if( !(*it).isEmpty() )
145 output << (*it).toLocal8Bit();
147 output << sep;
151 return buff;
154 void KJavaProcess::storeSize( QByteArray* buff )
156 const int size = buff->size() - 8; //subtract out the length of the size_str
157 const QString size_str = QString("%1").arg( size, 8 );
158 kDebug(6100) << "KJavaProcess::storeSize, size = " << size_str;
160 for( int i = 0; i < 8; ++i )
161 buff->data()[ i ] = size_str[i].toLatin1();
164 void KJavaProcess::send( char cmd_code, const QStringList& args )
166 if( isRunning() )
168 QByteArray buff = addArgs( cmd_code, args );
169 storeSize( &buff );
170 kDebug(6100) << "<KJavaProcess::send " << (int)cmd_code;
171 write( buff );
175 void KJavaProcess::send( char cmd_code, const QStringList& args,
176 const QByteArray& data )
178 if( isRunning() )
180 kDebug(6100) << "KJavaProcess::send, qbytearray is size = " << data.size();
182 QByteArray buff = addArgs( cmd_code, args );
183 buff += data;
185 storeSize( &buff );
186 write( buff );
190 bool KJavaProcess::invokeJVM()
192 QStringList args;
194 if( !d->classPath.isEmpty() )
196 args << "-classpath";
197 args << d->classPath;
200 //set the system properties, iterate through the qmap of system properties
201 QMap<QString,QString>::ConstIterator it = d->systemProps.constBegin();
202 const QMap<QString,QString>::ConstIterator itEnd = d->systemProps.constEnd();
204 for( ; it != itEnd; ++it )
206 if( !it.key().isEmpty() )
208 QString currarg = "-D" + it.key();
209 if( !it.value().isEmpty() )
210 currarg += '=' + it.value();
211 args << currarg;
215 //load the extra user-defined arguments
216 if( !d->extraArgs.isEmpty() )
218 KShell::Errors err;
219 args += KShell::splitArgs( d->extraArgs, KShell::AbortOnMeta, &err );
220 if( err != KShell::NoError )
221 kWarning(6100) << "Extra args for JVM cannot be parsed, arguments = " << d->extraArgs;
225 args << d->mainClass;
227 if ( !d->classArgs.isNull() )
228 args << d->classArgs;
230 kDebug(6100) << "Invoking JVM" << d->jvmPath << "now...with arguments = " << KShell::joinArgs(args);
232 setOutputChannelMode(KProcess::SeparateChannels);
233 setProgram( d->jvmPath, args );
234 start();
236 return waitForStarted();
239 void KJavaProcess::killJVM()
241 closeReadChannel( StandardOutput );
242 terminate();
245 /* In this method, read one command and send it to the d->appletServer
246 * then return, so we don't block the event handling
248 void KJavaProcess::slotReceivedData()
250 //read out the length of the message,
251 //read the message and send it to the applet server
252 char length[9] = { 0 };
253 const int num_bytes = read( length, 8 );
254 if( num_bytes == -1 )
256 kError(6100) << "could not read 8 characters for the message length!!!!" << endl;
257 return;
260 const QString lengthstr( length );
261 bool ok;
262 const int num_len = lengthstr.toInt( &ok );
263 if( !ok )
265 kError(6100) << "could not parse length out of: " << lengthstr << endl;
266 return;
269 //now parse out the rest of the message.
270 char* const msg = new char[num_len];
271 const int num_bytes_msg = read( msg, num_len );
272 if( num_bytes_msg == -1 || num_bytes_msg != num_len )
274 kError(6100) << "could not read the msg, num_bytes_msg = " << num_bytes_msg << endl;
275 delete[] msg;
276 return;
279 emit received( QByteArray( msg, num_len ) );
280 delete[] msg;
283 void KJavaProcess::slotExited()
285 int status = -1;
286 if ( exitStatus() == NormalExit ) {
287 status = exitCode();
289 kDebug(6100) << "jvm exited with status " << status;
290 emit exited(status);
293 #include "kjavaprocess.moc"