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"
26 #include <kio/kprotocolmanager.h>
28 #include <QtCore/QTextStream>
29 #include <QtCore/QMap>
33 class KJavaProcessPrivate
35 friend class KJavaProcess
;
42 QMap
<QString
, QString
> systemProps
;
45 KJavaProcess::KJavaProcess( QObject
* 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() ) );
58 d
->mainClass
= "-help";
61 KJavaProcess::~KJavaProcess()
63 if ( state() != NotRunning
)
65 kDebug(6100) << "stopping java process";
71 bool KJavaProcess::isRunning()
73 return state() != NotRunning
;
76 bool KJavaProcess::startJava()
81 void KJavaProcess::stopJava()
86 void KJavaProcess::setJVMPath( const QString
& 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
)
112 void KJavaProcess::setClassArgs( const QString
& 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.
122 QTextStream
output( &buff
, QIODevice::ReadWrite
);
125 //make space for the command size: 8 characters...
126 const QByteArray
space( " " );
132 //store the arguments...
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();
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
)
168 QByteArray buff
= addArgs( cmd_code
, args
);
170 kDebug(6100) << "<KJavaProcess::send " << (int)cmd_code
;
175 void KJavaProcess::send( char cmd_code
, const QStringList
& args
,
176 const QByteArray
& data
)
180 kDebug(6100) << "KJavaProcess::send, qbytearray is size = " << data
.size();
182 QByteArray buff
= addArgs( cmd_code
, args
);
190 bool KJavaProcess::invokeJVM()
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();
215 //load the extra user-defined arguments
216 if( !d
->extraArgs
.isEmpty() )
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
);
236 return waitForStarted();
239 void KJavaProcess::killJVM()
241 closeReadChannel( StandardOutput
);
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
;
260 const QString
lengthstr( length
);
262 const int num_len
= lengthstr
.toInt( &ok
);
265 kError(6100) << "could not parse length out of: " << lengthstr
<< endl
;
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
;
279 emit
received( QByteArray( msg
, num_len
) );
283 void KJavaProcess::slotExited()
286 if ( exitStatus() == NormalExit
) {
289 kDebug(6100) << "jvm exited with status " << status
;
293 #include "kjavaprocess.moc"