43 #include <QtCore/QTimer>
44 #include <QtCore/QPointer>
45 #include <QtCore/QDir>
46 #include <QtCore/QEventLoop>
47 #include <QtGui/QApplication>
48 #include <QtGui/QLabel>
49 #include <QtGui/QDialog>
50 #include <QtGui/QPushButton>
51 #include <QtGui/QLayout>
52 #include <QtCore/QRegExp>
56 #include <QtCore/QAbstractEventDispatcher>
58 #define KJAS_CREATE_CONTEXT (char)1
59 #define KJAS_DESTROY_CONTEXT (char)2
60 #define KJAS_CREATE_APPLET (char)3
61 #define KJAS_DESTROY_APPLET (char)4
62 #define KJAS_START_APPLET (char)5
63 #define KJAS_STOP_APPLET (char)6
64 #define KJAS_INIT_APPLET (char)7
65 #define KJAS_SHOW_DOCUMENT (char)8
66 #define KJAS_SHOW_URLINFRAME (char)9
67 #define KJAS_SHOW_STATUS (char)10
68 #define KJAS_RESIZE_APPLET (char)11
69 #define KJAS_GET_URLDATA (char)12
70 #define KJAS_URLDATA (char)13
71 #define KJAS_SHUTDOWN_SERVER (char)14
72 #define KJAS_JAVASCRIPT_EVENT (char)15
73 #define KJAS_GET_MEMBER (char)16
74 #define KJAS_CALL_MEMBER (char)17
75 #define KJAS_PUT_MEMBER (char)18
76 #define KJAS_DEREF_OBJECT (char)19
77 #define KJAS_AUDIOCLIP_PLAY (char)20
78 #define KJAS_AUDIOCLIP_LOOP (char)21
79 #define KJAS_AUDIOCLIP_STOP (char)22
80 #define KJAS_APPLET_STATE (char)23
81 #define KJAS_APPLET_FAILED (char)24
82 #define KJAS_DATA_COMMAND (char)25
83 #define KJAS_PUT_URLDATA (char)26
84 #define KJAS_PUT_DATA (char)27
85 #define KJAS_SECURITY_CONFIRM (char)28
86 #define KJAS_SHOW_CONSOLE (char)29
97 : jsstack(stack), args(a), ticket(counter++), ready(
false), exit (
false) {
98 jsstack.insert( ticket,
this );
101 jsstack.remove( ticket );
111 int JSStackFrame::counter = 0;
113 class KJavaAppletServerPrivate
117 KJavaAppletServerPrivate() : kssl( 0L ) {}
118 ~KJavaAppletServerPrivate() {
126 bool javaProcessFailed;
136 :
d(new KJavaAppletServerPrivate)
140 connect(
process, SIGNAL(received(QByteArray)),
146 d->appletLabel =
i18n(
"Loading Applet" );
147 d->javaProcessFailed =
false;
150 d->appletLabel =
i18n(
"Error: java executable not found" );
151 d->javaProcessFailed =
true;
168 return self->appletLabel();
175 return d->appletLabel;
183 self->d->counter = 0;
186 ++(
self->d->counter);
192 --(
self->d->counter);
194 if(
self->d->counter == 0 )
201 if( group.
readEntry(
"ShutdownAppletServer",
true ) )
203 const int value = group.
readEntry(
"AppletServerTimeout", 60 );
204 QTimer::singleShot( value*1000,
self, SLOT(
checkShutdown()) );
211 if(
self->d->counter == 0 )
220 KConfig configFile (
"konquerorrc" );
226 if ( !jPath.isEmpty() && jPath !=
"java" )
229 if( jPath[jPath.length()-1] ==
'/' )
230 jPath.remove(jPath.length()-1, 1);
233 if( dir.exists(
"bin/java" ) )
235 jvm_path = jPath +
"/bin/java";
237 else if (dir.exists(
"/jre/bin/java" ) )
239 jvm_path = jPath +
"/jre/bin/java";
241 else if( QFile::exists(jPath) )
253 kDebug(6100) <<
"kjava_class = " << kjava_class;
254 if( kjava_class.isNull() )
257 QDir
dir( kjava_class );
259 kDebug(6100) <<
"dir = " << dir.absolutePath();
261 const QStringList entries = dir.entryList(QDir::nameFiltersFromString(
"*.jar" ));
262 kDebug(6100) <<
"entries = " << entries.join(
":" );
266 QStringList::ConstIterator it = entries.begin();
267 const QStringList::ConstIterator itEnd = entries.end();
268 for( ; it != itEnd; ++it )
270 if( !classes.isEmpty() )
272 classes += dir.absoluteFilePath( *it );
281 if( config.
readEntry(
"UseSecurityManager",
true ) )
287 "org.kde.kjas.server.KJASSecurityManager" );
290 d->useKIO = config.
readEntry(
"UseKio",
false);
303 const KUrl dummyURL(
"http://www.kde.org/" );
305 kDebug(6100) <<
"httpProxy is " << httpProxy;
307 const KUrl url( httpProxy );
319 if ( d->javaProcessFailed )
return;
321 d->contexts.insert( contextId, context );
324 args.append( QString::number( contextId ) );
331 if ( d->javaProcessFailed )
return;
332 d->contexts.remove( contextId );
335 args.append( QString::number( contextId ) );
357 if ( d->javaProcessFailed )
return false;
360 args.append( QString::number( contextId ) );
361 args.append( QString::number( appletId ) );
365 args.append( clazzName );
366 args.append( baseURL );
368 args.append( password );
369 args.append( authname );
370 args.append( codeBase );
371 args.append( jarFile );
373 args.append( QString::number( size.width() ) );
374 args.append( QString::number( size.height() ) );
376 args.append( windowTitle );
379 const int num = params.count();
381 args.append( num_params );
386 for( ; it != itEnd; ++it )
388 args.append( it.key() );
389 args.append( it.value() );
399 if ( d->javaProcessFailed )
return;
401 args.append( QString::number( contextId ) );
402 args.append( QString::number( appletId ) );
409 if ( d->javaProcessFailed )
return;
411 args.append( QString::number(contextId) );
412 args.append( QString::number(appletId) );
419 if ( d->javaProcessFailed )
return;
421 args.append( QString::number(contextId) );
422 args.append( QString::number(appletId) );
429 if ( d->javaProcessFailed )
return;
431 args.append( QString::number(contextId) );
432 args.append( QString::number(appletId) );
438 if ( d->javaProcessFailed )
return;
446 args.append( QString::number(loaderID) );
447 args.append( QString::number(code) );
454 const KIOJobMap::iterator it = d->kiojobs.find( loaderID );
455 if (it != d->kiojobs.end()) {
456 it.value()->deleteLater();
457 d->kiojobs.erase( it );
466 process->waitForFinished( 10000 );
476 const int qb_size = qb.size();
479 const char cmd_code = qb[ index++ ];
484 while( index < qb_size && qb[index] != 0 )
486 contextID += qb[ index++ ];
489 const int ID_num = contextID.toInt( &ok );
507 KIOJobMap::iterator it = d->kiojobs.find( ID_num );
508 if (ok && it != d->kiojobs.end()) {
510 qba = QByteArray::fromRawData(qb.data() + index, qb.size() - index - 1);
511 it.value()->data(qba);
512 qba = QByteArray::fromRawData(qb.data() + index, qb.size() - index - 1);
514 kDebug(6100) <<
"PutData(" << ID_num <<
") size=" << qb.size() - index;
516 kError(6100) <<
"PutData error " << ok << endl;
520 while( index < qb_size )
522 int sep_pos = qb.indexOf( (
char) 0, index );
524 kError(6100) <<
"Missing separation byte" << endl;
528 args.append( QString::fromLocal8Bit( qb.data() + index, sep_pos - index ) );
536 cmd = QLatin1String(
"showdocument" );
540 cmd = QLatin1String(
"showurlinframe" );
544 cmd = QLatin1String(
"showstatus" );
548 cmd = QLatin1String(
"resizeapplet" );
552 if (ok && !args.empty() ) {
554 kDebug(6100) <<
"GetURLData(" << ID_num <<
") url=" << args.first();
556 kError(6100) <<
"GetURLData error " << ok <<
" args:" << args.size() << endl;
559 if (ok && !args.empty()) {
561 d->kiojobs.insert(ID_num, job);
563 kDebug(6100) <<
"PutURLData(" << ID_num <<
") url=" << args.first();
565 kError(6100) <<
"PutURLData error " << ok <<
" args:" << args.size() << endl;
568 if (ok && !args.empty()) {
569 const int cmd = args.first().toInt( &ok );
570 KIOJobMap::iterator it = d->kiojobs.find( ID_num );
571 if (ok && it != d->kiojobs.end())
572 it.value()->jobCommand( cmd );
573 kDebug(6100) <<
"KIO Data command: " << ID_num <<
" " << args.first();
575 kError(6100) <<
"KIO Data command error " << ok <<
" args:" << args.size() << endl;
578 cmd = QLatin1String(
"JS_Event" );
581 kDebug(6100) <<
"Javascript request: "<< contextID
582 <<
" code: " << args[0] << endl;
584 kError(6100) <<
"Expected args not to be empty!" << endl;
592 const int ticket = args[0].toInt();
593 JSStack::iterator it = d->jsstack.find(ticket);
594 if (it != d->jsstack.end()) {
595 kDebug(6100) <<
"slotJavaRequest: " << ticket;
597 it.value()->args.operator=(args);
598 it.value()->ready =
true;
599 it.value()->exit =
true;
601 kDebug(6100) <<
"Error: Missed return member data";
603 kError(6100) <<
"Expected args not to be empty!" << endl;
608 cmd = QLatin1String(
"audioclip_play" );
610 kDebug(6100) <<
"Audio Play: url=" << args[0];
612 kError(6100) <<
"Expected args not to be empty!" << endl;
616 cmd = QLatin1String(
"audioclip_loop" );
618 kDebug(6100) <<
"Audio Loop: url=" << args[0];
620 kError(6100) <<
"Expected args not to be empty!" << endl;
624 cmd = QLatin1String(
"audioclip_stop" );
626 kDebug(6100) <<
"Audio Stop: url=" << args[0];
628 kError(6100) <<
"Expected args not to be empty!" << endl;
633 kDebug(6100) <<
"Applet State Notification for Applet " << args[0] <<
". New state=" << args[1];
635 kError(6100) <<
"Expected args not to be empty!" << endl;
637 cmd = QLatin1String(
"AppletStateNotification" );
641 kDebug(6100) <<
"Applet " << args[0] <<
" Failed: " << args[1];
643 kError(6100) <<
"Expected args not to be empty!" << endl;
645 cmd = QLatin1String(
"AppletFailed" );
655 }
else if (args.size() > 2) {
656 const int certsnr = args[1].toInt();
657 Q_ASSERT(args.size() > certsnr + 1);
660 for (
int i = certsnr - 1; i >= 0; --i) {
661 const QByteArray &arg = args[i + 2].toLatin1();
671 QRegExp reg(
QString(
"/[A-Z]+="));
673 while ((pos = subject.indexOf(reg, pos)) > -1)
674 subject.replace(pos, 1,
QString(
"\n "));
675 text += subject.mid(1);
678 kDebug(6100) <<
"Security confirm " << args.first() << certs.count();
679 if ( !certs.isEmpty() ) {
687 sl.push_front( answer );
688 sl.push_front( QString::number(ID_num) );
700 kError(6100) <<
"could not parse out contextID to call command on" << endl;
707 else if (cmd !=
"AppletStateNotification")
708 kError(6100) <<
"no context object for this id" << endl;
713 QAbstractEventDispatcher::instance()->unregisterTimers(
this);
717 kDebug(6100) <<
"KJavaAppletServer::endWaitForReturnData";
719 JSStack::iterator it = d->jsstack.begin();
720 JSStack::iterator itEnd = d->jsstack.end();
721 for (; it != itEnd; ++it)
722 it.value()->exit =
true;
727 kDebug(6100) <<
"KJavaAppletServer::timerEvent timeout";
731 kDebug(6100) <<
">KJavaAppletServer::waitForReturnData";
734 while (!frame->exit) {
735 QAbstractEventDispatcher::instance()->processEvents (QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
737 if (d->jsstack.size() <= 1)
739 kDebug(6100) <<
"<KJavaAppletServer::waitForReturnData stacksize:" << d->jsstack.size();
743 JSStackFrame frame( d->jsstack, ret_args );
744 args.push_front( QString::number(frame.ticket) );
754 JSStackFrame frame( d->jsstack, ret_args );
755 args.push_front( QString::number(frame.ticket) );
760 return frame.ready && ret_args.count() > 0 && ret_args[0].toInt();
764 JSStackFrame frame( d->jsstack, ret_args );
765 args.push_front( QString::number(frame.ticket) );
783 :
QObject(parent), m_button(
"no")
787 QPointer<QDialog> dialog =
new QDialog( static_cast<QWidget*>(parent()) );
789 dialog->setObjectName(
"PermissionDialog");
790 QSizePolicy sizeplcy( QSizePolicy::Minimum, QSizePolicy::Minimum);
791 sizeplcy.setHeightForWidth(dialog->sizePolicy().hasHeightForWidth());
792 dialog->setSizePolicy(sizeplcy);
793 dialog->setModal(
true );
794 dialog->setWindowTitle(
i18n(
"Security Alert") );
796 QVBoxLayout*
const dialogLayout =
new QVBoxLayout( dialog );
797 dialogLayout->setObjectName(
"dialogLayout");
799 dialogLayout->addWidget(
new QLabel(
i18n(
"Do you grant Java applet with certificate(s):"), dialog ) );
800 dialogLayout->addWidget(
new QLabel( cert, dialog ) );
801 dialogLayout->addWidget(
new QLabel(
i18n(
"the following permission"), dialog ) );
802 dialogLayout->addWidget(
new QLabel( perm, dialog ) );
803 QSpacerItem*
const spacer2 =
new QSpacerItem( 20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding );
804 dialogLayout->addItem( spacer2 );
806 QHBoxLayout*
const buttonLayout =
new QHBoxLayout();
807 buttonLayout->setMargin(0);
808 buttonLayout->setObjectName(
"buttonLayout");
811 no->setDefault(
true );
812 buttonLayout->addWidget( no );
815 buttonLayout->addWidget( reject );
818 buttonLayout->addWidget( yes );
821 buttonLayout->addWidget( grant );
822 dialogLayout->addLayout( buttonLayout );
823 dialog->resize( dialog->minimumSizeHint() );
826 connect( no, SIGNAL(clicked()),
this, SLOT(clicked()) );
827 connect( reject, SIGNAL(clicked()),
this, SLOT(clicked()) );
828 connect( yes, SIGNAL(clicked()),
this, SLOT(clicked()) );
829 connect( grant, SIGNAL(clicked()),
this, SLOT(clicked()) );
840 void PermissionDialog::clicked()
842 m_button = sender()->objectName();
843 static_cast<const QWidget*
>(sender())->parentWidget()->close();
846 #include "kjavaappletserver.moc"
KJavaAppletServer()
Create the applet server.
#define KJAS_DEREF_OBJECT
QString i18n(const char *text)
QString readPathEntry(const QString &pKey, const QString &aDefault) const
#define KJAS_CREATE_CONTEXT
#define KJAS_SHUTDOWN_SERVER
bool startJava()
Invoke the JVM with the parameters that have been set.
KSSLValidation validate()
void waitForReturnData(JSStackFrame *)
void createContext(int contextId, KJavaAppletContext *context)
Create an applet context with the specified id.
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
#define KJAS_SHOW_URLINFRAME
static QString getAppletLabel()
This allows the KJavaAppletWidget to display some feedback in a QLabel while the applet is being load...
void removeDataJob(int loaderID)
Removes KJavaDownloader from the list (deletes it too).
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KConfigGroup group(const QByteArray &group)
#define KJAS_AUDIOCLIP_STOP
void stopApplet(int contextId, int appletId)
Stop the specified applet.
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QString getSubject() const
void setMainClass(const QString &clazzName)
The class to be called when startJava() is called.
#define KJAS_AUDIOCLIP_LOOP
KSharedConfigPtr config()
void setChain(void *stack_of_x509)
void setSystemProperty(const QString &name, const QString &value)
Set a property on the java command line as -Dname=value, or -Dname if value is QString().
static QString verifyText(KSSLValidation x)
bool createApplet(int contextId, int appletId, const QString &name, const QString &clazzName, const QString &baseURL, const QString &user, const QString &password, const QString &authname, const QString &codeBase, const QString &jarFile, QSize size, const QMap< QString, QString > ¶ms, const QString &windowTitle)
Create an applet in the specified context with the specified id.
QString exec(const QString &cert, const QString &perm)
void send(char cmd_code, const QStringList &args)
Sends a command to the KJAS Applet Server by building a QByteArray out of the data, and then writes it standard out.
void initApplet(int contextId, int appletId)
This should be called by the KJavaAppletWidget.
void derefObject(QStringList &args)
#define KJAS_DESTROY_CONTEXT
#define KJAS_RESIZE_APPLET
void showConsole()
Show java console.
#define KJAS_APPLET_FAILED
#define KJAS_DATA_COMMAND
bool putMember(QStringList &args)
void setClasspath(const QString &classpath)
This will set the classpath the Java process will use.
void setupJava(KJavaProcess *p)
static QString proxyForUrl(const KUrl &url)
bool getMember(QStringList &args, QStringList &ret_args)
QMap< int, KJavaKIOJob * > KIOJobMap
void sendURLData(int loaderID, int code, const QByteArray &data)
Send data we got back from a KJavaDownloader back to the appropriate class loader.
#define KJAS_SHOW_CONSOLE
void destroyContext(int contextId)
Destroy the applet context with the specified id.
static KSSLCertificate * fromString(const QByteArray &cert)
void endWaitForReturnData()
#define KJAS_SHOW_DOCUMENT
static KJavaAppletServer * self
void setJVMPath(const QString &path)
Used to specify the path to the Java executable to be run.
QString dir(const QString &fileClass)
#define KJAS_DESTROY_APPLET
static bool doesSSLWork()
#define KJAS_AUDIOCLIP_PLAY
void processCmd(QString cmd, QStringList args)
use this for applet call backs, the AppletServer calls this directly.
void startApplet(int contextId, int appletId)
Start the specified applet.
PermissionDialog(QWidget *)
#define KJAS_APPLET_STATE
#define KJAS_START_APPLET
static void freeJavaServer()
When you are done using your reference to the AppletServer, you must dereference it by calling freeJa...
bool callMember(QStringList &args, QStringList &ret_args)
void quit()
Shut down the KJAS server.
#define KJAS_SECURITY_CONFIRM
void timerEvent(QTimerEvent *)
void slotJavaRequest(const QByteArray &qb)
void setExtraArgs(const QString &args)
Extra flags passed to the JVM.
#define KJAS_JAVASCRIPT_EVENT
T readEntry(const QString &key, const T &aDefault) const
#define KJAS_CREATE_APPLET
static KJavaAppletServer * allocateJavaServer()
A factory method that returns the default server.
QMap< int, JSStackFrame * > JSStack
void destroyApplet(int contextId, int appletId)
Destroy an applet in the specified context with the specified id.