KHTML
kjavaprocess.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kjavaprocess.h"
00023
00024 #include <kdebug.h>
00025 #include <kshell.h>
00026 #include <kio/kprotocolmanager.h>
00027
00028 #include <QtCore/QTextStream>
00029 #include <QtCore/QMap>
00030
00031 #include <config.h>
00032
00033 class KJavaProcessPrivate
00034 {
00035 friend class KJavaProcess;
00036 private:
00037 QString jvmPath;
00038 QString classPath;
00039 QString mainClass;
00040 QString extraArgs;
00041 QString classArgs;
00042 QMap<QString, QString> systemProps;
00043 };
00044
00045 KJavaProcess::KJavaProcess( QObject* parent )
00046 : KProcess( parent ),
00047 d(new KJavaProcessPrivate)
00048
00049 {
00050 connect( this, SIGNAL( readyReadStandardOutput() ),
00051 this, SLOT( slotReceivedData() ) );
00052 connect( this, SIGNAL( finished( int, QProcess::ExitStatus ) ),
00053 this, SLOT( slotExited() ) );
00054 connect( this, SIGNAL( error( QProcess::ProcessError ) ),
00055 this, SLOT( slotExited() ) );
00056
00057 d->jvmPath = "java";
00058 d->mainClass = "-help";
00059 }
00060
00061 KJavaProcess::~KJavaProcess()
00062 {
00063 if ( state() != NotRunning )
00064 {
00065 kDebug(6100) << "stopping java process";
00066 stopJava();
00067 }
00068 delete d;
00069 }
00070
00071 bool KJavaProcess::isRunning()
00072 {
00073 return state() != NotRunning;
00074 }
00075
00076 bool KJavaProcess::startJava()
00077 {
00078 return invokeJVM();
00079 }
00080
00081 void KJavaProcess::stopJava()
00082 {
00083 killJVM();
00084 }
00085
00086 void KJavaProcess::setJVMPath( const QString& path )
00087 {
00088 d->jvmPath = path;
00089 }
00090
00091 void KJavaProcess::setClasspath( const QString& classpath )
00092 {
00093 d->classPath = classpath;
00094 }
00095
00096 void KJavaProcess::setSystemProperty( const QString& name,
00097 const QString& value )
00098 {
00099 d->systemProps.insert( name, value );
00100 }
00101
00102 void KJavaProcess::setMainClass( const QString& className )
00103 {
00104 d->mainClass = className;
00105 }
00106
00107 void KJavaProcess::setExtraArgs( const QString& args )
00108 {
00109 d->extraArgs = args;
00110 }
00111
00112 void KJavaProcess::setClassArgs( const QString& args )
00113 {
00114 d->classArgs = args;
00115 }
00116
00117
00118 QByteArray KJavaProcess::addArgs( char cmd_code, const QStringList& args )
00119 {
00120
00121 QByteArray buff;
00122 QTextStream output( &buff, QIODevice::ReadWrite );
00123 const char sep = 0;
00124
00125
00126 const QByteArray space( " " );
00127 output << space;
00128
00129
00130 output << cmd_code;
00131
00132
00133 if( args.isEmpty() )
00134 {
00135 output << sep;
00136 }
00137 else
00138 {
00139 QStringList::ConstIterator it = args.begin();
00140 const QStringList::ConstIterator itEnd = args.end();
00141 for( ; it != itEnd; ++it )
00142 {
00143 if( !(*it).isEmpty() )
00144 {
00145 output << (*it).toLocal8Bit();
00146 }
00147 output << sep;
00148 }
00149 }
00150
00151 return buff;
00152 }
00153
00154 void KJavaProcess::storeSize( QByteArray* buff )
00155 {
00156 const int size = buff->size() - 8;
00157 const QString size_str = QString("%1").arg( size, 8 );
00158 kDebug(6100) << "KJavaProcess::storeSize, size = " << size_str;
00159
00160 for( int i = 0; i < 8; ++i )
00161 buff->data()[ i ] = size_str[i].toLatin1();
00162 }
00163
00164 void KJavaProcess::send( char cmd_code, const QStringList& args )
00165 {
00166 if( isRunning() )
00167 {
00168 QByteArray buff = addArgs( cmd_code, args );
00169 storeSize( &buff );
00170 kDebug(6100) << "<KJavaProcess::send " << (int)cmd_code;
00171 write( buff );
00172 }
00173 }
00174
00175 void KJavaProcess::send( char cmd_code, const QStringList& args,
00176 const QByteArray& data )
00177 {
00178 if( isRunning() )
00179 {
00180 kDebug(6100) << "KJavaProcess::send, qbytearray is size = " << data.size();
00181
00182 QByteArray buff = addArgs( cmd_code, args );
00183 buff += data;
00184
00185 storeSize( &buff );
00186 write( buff );
00187 }
00188 }
00189
00190 bool KJavaProcess::invokeJVM()
00191 {
00192 QStringList args;
00193
00194 if( !d->classPath.isEmpty() )
00195 {
00196 args << "-classpath";
00197 args << d->classPath;
00198 }
00199
00200
00201 QMap<QString,QString>::ConstIterator it = d->systemProps.constBegin();
00202 const QMap<QString,QString>::ConstIterator itEnd = d->systemProps.constEnd();
00203
00204 for( ; it != itEnd; ++it )
00205 {
00206 if( !it.key().isEmpty() )
00207 {
00208 QString currarg = "-D" + it.key();
00209 if( !it.value().isEmpty() )
00210 currarg += '=' + it.value();
00211 args << currarg;
00212 }
00213 }
00214
00215
00216 if( !d->extraArgs.isEmpty() )
00217 {
00218 KShell::Errors err;
00219 args += KShell::splitArgs( d->extraArgs, KShell::AbortOnMeta, &err );
00220 if( err != KShell::NoError )
00221 kWarning(6100) << "Extra args for JVM cannot be parsed, arguments = " << d->extraArgs;
00222
00223 }
00224
00225 args << d->mainClass;
00226
00227 if ( !d->classArgs.isNull() )
00228 args << d->classArgs;
00229
00230 kDebug(6100) << "Invoking JVM" << d->jvmPath << "now...with arguments = " << KShell::joinArgs(args);
00231
00232 setOutputChannelMode(KProcess::SeparateChannels);
00233 setProgram( d->jvmPath, args );
00234 start();
00235
00236 return waitForStarted();
00237 }
00238
00239 void KJavaProcess::killJVM()
00240 {
00241 closeReadChannel( StandardOutput );
00242 terminate();
00243 }
00244
00245
00246
00247
00248 void KJavaProcess::slotReceivedData()
00249 {
00250
00251
00252 char length[9] = { 0 };
00253 const int num_bytes = read( length, 8 );
00254 if( num_bytes == -1 )
00255 {
00256 kError(6100) << "could not read 8 characters for the message length!!!!" << endl;
00257 return;
00258 }
00259
00260 const QString lengthstr( length );
00261 bool ok;
00262 const int num_len = lengthstr.toInt( &ok );
00263 if( !ok )
00264 {
00265 kError(6100) << "could not parse length out of: " << lengthstr << endl;
00266 return;
00267 }
00268
00269
00270 char* const msg = new char[num_len];
00271 const int num_bytes_msg = read( msg, num_len );
00272 if( num_bytes_msg == -1 || num_bytes_msg != num_len )
00273 {
00274 kError(6100) << "could not read the msg, num_bytes_msg = " << num_bytes_msg << endl;
00275 delete[] msg;
00276 return;
00277 }
00278
00279 emit received( QByteArray( msg, num_len ) );
00280 delete[] msg;
00281 }
00282
00283 void KJavaProcess::slotExited()
00284 {
00285 int status = -1;
00286 if ( exitStatus() == NormalExit ) {
00287 status = exitCode();
00288 }
00289 kDebug(6100) << "jvm exited with status " << status;
00290 emit exited(status);
00291 }
00292
00293 #include "kjavaprocess.moc"