diff options
Diffstat (limited to 'src/VBox/Main/glue')
-rw-r--r-- | src/VBox/Main/glue/AutoLock.cpp | 85 | ||||
-rw-r--r-- | src/VBox/Main/glue/ErrorInfo.cpp | 22 | ||||
-rw-r--r-- | src/VBox/Main/glue/EventQueue.cpp | 670 | ||||
-rw-r--r-- | src/VBox/Main/glue/NativeEventQueue.cpp | 655 | ||||
-rw-r--r-- | src/VBox/Main/glue/com.cpp | 77 | ||||
-rw-r--r-- | src/VBox/Main/glue/constants-python.xsl | 205 | ||||
-rw-r--r-- | src/VBox/Main/glue/errorprint.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Main/glue/glue-java.xsl | 3113 | ||||
-rw-r--r-- | src/VBox/Main/glue/initterm.cpp | 107 | ||||
-rw-r--r-- | src/VBox/Main/glue/string.cpp | 4 | ||||
-rw-r--r-- | src/VBox/Main/glue/tests/Makefile | 2 | ||||
-rw-r--r-- | src/VBox/Main/glue/tests/TestVBox.java | 88 | ||||
-rw-r--r-- | src/VBox/Main/glue/tests/TestVBoxNATEngine.java | 187 | ||||
-rw-r--r--[-rwxr-xr-x] | src/VBox/Main/glue/vboxapi.py | 1057 | ||||
-rw-r--r-- | src/VBox/Main/glue/xpcom/helpers.cpp | 5 |
15 files changed, 4041 insertions, 2238 deletions
diff --git a/src/VBox/Main/glue/AutoLock.cpp b/src/VBox/Main/glue/AutoLock.cpp index bf1d4c9a..fa909b9c 100644 --- a/src/VBox/Main/glue/AutoLock.cpp +++ b/src/VBox/Main/glue/AutoLock.cpp @@ -1,10 +1,10 @@ +/* $Id: AutoLock.cpp $ */ /** @file - * - * Automatic locks, implementation + * Automatic locks, implementation. */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -15,6 +15,16 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ + +/******************************************************************************* +* Defined Constants And Macros * +*******************************************************************************/ +#define GLUE_USE_CRITSECTRW + + +/******************************************************************************* +* Header Files * +*******************************************************************************/ #include <iprt/cdefs.h> #include <iprt/critsect.h> #include <iprt/thread.h> @@ -38,6 +48,7 @@ #include <list> #include <map> + namespace util { @@ -133,11 +144,15 @@ struct RWLockHandle::Data Data() { } - RTSEMRW sem; - VBoxLockingClass lockClass; +#ifdef GLUE_USE_CRITSECTRW + mutable RTCRITSECTRW CritSect; +#else + RTSEMRW sem; +#endif + VBoxLockingClass lockClass; #ifdef VBOX_WITH_MAIN_LOCK_VALIDATION - com::Utf8Str strDescription; + com::Utf8Str strDescription; #endif }; @@ -146,64 +161,110 @@ RWLockHandle::RWLockHandle(VBoxLockingClass lockClass) m = new Data(); m->lockClass = lockClass; - #ifdef VBOX_WITH_MAIN_LOCK_VALIDATION m->strDescription = com::Utf8StrFmt("r/w %RCv", this); - int vrc = RTSemRWCreateEx(&m->sem, 0 /*fFlags*/, g_mapLockValidationClasses[lockClass], RTLOCKVAL_SUB_CLASS_ANY, NULL); +#endif + +#ifdef GLUE_USE_CRITSECTRW +# ifdef VBOX_WITH_MAIN_LOCK_VALIDATION + int vrc = RTCritSectRwInitEx(&m->CritSect, 0 /*fFlags*/, g_mapLockValidationClasses[lockClass], RTLOCKVAL_SUB_CLASS_ANY, NULL); +# else + int vrc = RTCritSectRwInitEx(&m->CritSect, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL); +# endif #else +# ifdef VBOX_WITH_MAIN_LOCK_VALIDATION + int vrc = RTSemRWCreateEx(&m->sem, 0 /*fFlags*/, g_mapLockValidationClasses[lockClass], RTLOCKVAL_SUB_CLASS_ANY, NULL); +# else int vrc = RTSemRWCreateEx(&m->sem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL); +# endif #endif AssertRC(vrc); } /*virtual*/ RWLockHandle::~RWLockHandle() { +#ifdef GLUE_USE_CRITSECTRW + RTCritSectRwDelete(&m->CritSect); +#else RTSemRWDestroy(m->sem); +#endif delete m; } /*virtual*/ bool RWLockHandle::isWriteLockOnCurrentThread() const { +#ifdef GLUE_USE_CRITSECTRW + return RTCritSectRwIsWriteOwner(&m->CritSect); +#else return RTSemRWIsWriteOwner(m->sem); +#endif } /*virtual*/ void RWLockHandle::lockWrite(LOCKVAL_SRC_POS_DECL) { -#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION - int vrc = RTSemRWRequestWriteDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); +#ifdef GLUE_USE_CRITSECTRW +# ifdef VBOX_WITH_MAIN_LOCK_VALIDATION + int vrc = RTCritSectRwEnterExclDebug(&m->CritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); +# else + int vrc = RTCritSectRwEnterExcl(&m->CritSect); +# endif #else +# ifdef VBOX_WITH_MAIN_LOCK_VALIDATION + int vrc = RTSemRWRequestWriteDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); +# else int vrc = RTSemRWRequestWrite(m->sem, RT_INDEFINITE_WAIT); +# endif #endif AssertRC(vrc); } /*virtual*/ void RWLockHandle::unlockWrite() { +#ifdef GLUE_USE_CRITSECTRW + int vrc = RTCritSectRwLeaveExcl(&m->CritSect); +#else int vrc = RTSemRWReleaseWrite(m->sem); +#endif AssertRC(vrc); } /*virtual*/ void RWLockHandle::lockRead(LOCKVAL_SRC_POS_DECL) { -#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION - int vrc = RTSemRWRequestReadDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); +#ifdef GLUE_USE_CRITSECTRW +# ifdef VBOX_WITH_MAIN_LOCK_VALIDATION + int vrc = RTCritSectRwEnterSharedDebug(&m->CritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); +# else + int vrc = RTCritSectRwEnterShared(&m->CritSect); +# endif #else +# ifdef VBOX_WITH_MAIN_LOCK_VALIDATION + int vrc = RTSemRWRequestReadDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); +# else int vrc = RTSemRWRequestRead(m->sem, RT_INDEFINITE_WAIT); +# endif #endif AssertRC(vrc); } /*virtual*/ void RWLockHandle::unlockRead() { +#ifdef GLUE_USE_CRITSECTRW + int vrc = RTCritSectRwLeaveShared(&m->CritSect); +#else int vrc = RTSemRWReleaseRead(m->sem); +#endif AssertRC(vrc); } /*virtual*/ uint32_t RWLockHandle::writeLockLevel() const { /* Note! This does not include read recursions done by the writer! */ +#ifdef GLUE_USE_CRITSECTRW + return RTCritSectRwGetWriteRecursion(&m->CritSect); +#else return RTSemRWGetWriteRecursion(m->sem); +#endif } #ifdef VBOX_WITH_MAIN_LOCK_VALIDATION diff --git a/src/VBox/Main/glue/ErrorInfo.cpp b/src/VBox/Main/glue/ErrorInfo.cpp index 13cdee83..149708f5 100644 --- a/src/VBox/Main/glue/ErrorInfo.cpp +++ b/src/VBox/Main/glue/ErrorInfo.cpp @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -43,12 +43,23 @@ namespace com // //////////////////////////////////////////////////////////////////////////////// +HRESULT ErrorInfo::getVirtualBoxErrorInfo(ComPtr<IVirtualBoxErrorInfo> &pVirtualBoxErrorInfo) +{ + HRESULT rc = S_OK; + if (mErrorInfo) + rc = mErrorInfo.queryInterfaceTo(pVirtualBoxErrorInfo.asOutParam()); + else + pVirtualBoxErrorInfo.setNull(); + return rc; +} + void ErrorInfo::copyFrom(const ErrorInfo &x) { mIsBasicAvailable = x.mIsBasicAvailable; mIsFullAvailable = x.mIsFullAvailable; mResultCode = x.mResultCode; + mResultDetail = x.mResultDetail; mInterfaceID = x.mInterfaceID; mComponent = x.mComponent; mText = x.mText; @@ -77,6 +88,7 @@ void ErrorInfo::cleanup() } mResultCode = S_OK; + mResultDetail = 0; mInterfaceID.clear(); mComponent.setNull(); mText.setNull(); @@ -224,12 +236,16 @@ void ErrorInfo::init(IVirtualBoxErrorInfo *info) HRESULT rc = E_FAIL; bool gotSomething = false; bool gotAll = true; - LONG lrc; + LONG lrc, lrd; rc = info->COMGETTER(ResultCode)(&lrc); mResultCode = lrc; gotSomething |= SUCCEEDED(rc); gotAll &= SUCCEEDED(rc); + rc = info->COMGETTER(ResultDetail)(&lrd); mResultDetail = lrd; + gotSomething |= SUCCEEDED(rc); + gotAll &= SUCCEEDED(rc); + Bstr iid; rc = info->COMGETTER(InterfaceID)(iid.asOutParam()); gotSomething |= SUCCEEDED(rc); @@ -266,6 +282,8 @@ void ErrorInfo::init(IVirtualBoxErrorInfo *info) mIsBasicAvailable = gotSomething; mIsFullAvailable = gotAll; + mErrorInfo = info; + AssertMsg(gotSomething, ("Nothing to fetch!\n")); } diff --git a/src/VBox/Main/glue/EventQueue.cpp b/src/VBox/Main/glue/EventQueue.cpp index d5a09c69..c918c993 100644 --- a/src/VBox/Main/glue/EventQueue.cpp +++ b/src/VBox/Main/glue/EventQueue.cpp @@ -1,11 +1,10 @@ /* $Id: EventQueue.cpp $ */ /** @file - * MS COM / XPCOM Abstraction Layer: - * Event and EventQueue class declaration + * Event queue class declaration. */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -16,23 +15,18 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -#include "VBox/com/EventQueue.h" +/** @todo Adapt / update documentation! */ -#ifdef RT_OS_DARWIN -# include <CoreFoundation/CFRunLoop.h> -#endif +#include "VBox/com/EventQueue.h" -#if defined(VBOX_WITH_XPCOM) && !defined(RT_OS_DARWIN) && !defined(RT_OS_OS2) -# define USE_XPCOM_QUEUE -#endif +#include <iprt/asm.h> +#include <new> /* For bad_alloc. */ #include <iprt/err.h> +#include <iprt/semaphore.h> #include <iprt/time.h> #include <iprt/thread.h> #include <iprt/log.h> -#ifdef USE_XPCOM_QUEUE -# include <errno.h> -#endif namespace com { @@ -40,430 +34,33 @@ namespace com // EventQueue class //////////////////////////////////////////////////////////////////////////////// -#ifndef VBOX_WITH_XPCOM - -# define CHECK_THREAD_RET(ret) \ - do { \ - AssertMsg(GetCurrentThreadId() == mThreadId, ("Must be on event queue thread!")); \ - if (GetCurrentThreadId() != mThreadId) \ - return ret; \ - } while (0) - -/** Magic LPARAM value for the WM_USER messages that we're posting. - * @remarks This magic value is duplicated in - * vboxapi/PlatformMSCOM::interruptWaitEvents(). */ -#define EVENTQUEUE_WIN_LPARAM_MAGIC UINT32_C(0xf241b819) - - -#else // VBOX_WITH_XPCOM - -# define CHECK_THREAD_RET(ret) \ - do { \ - if (!mEventQ) \ - return ret; \ - BOOL isOnCurrentThread = FALSE; \ - mEventQ->IsOnCurrentThread(&isOnCurrentThread); \ - AssertMsg(isOnCurrentThread, ("Must be on event queue thread!")); \ - if (!isOnCurrentThread) \ - return ret; \ - } while (0) - -#endif // VBOX_WITH_XPCOM - -/** Pointer to the main event queue. */ -EventQueue *EventQueue::sMainQueue = NULL; - - -#ifdef VBOX_WITH_XPCOM - -struct MyPLEvent : public PLEvent -{ - MyPLEvent(Event *e) : event(e) {} - Event *event; -}; - -/* static */ -void *PR_CALLBACK com::EventQueue::plEventHandler(PLEvent *self) -{ - Event *ev = ((MyPLEvent *)self)->event; - if (ev) - ev->handler(); - else - { - EventQueue *eq = (EventQueue *)self->owner; - Assert(eq); - eq->mInterrupted = true; - } - return NULL; -} - -/* static */ -void PR_CALLBACK com::EventQueue::plEventDestructor(PLEvent *self) -{ - Event *ev = ((MyPLEvent *)self)->event; - if (ev) - delete ev; - delete self; -} - -#endif // VBOX_WITH_XPCOM - -/** - * Constructs an event queue for the current thread. - * - * Currently, there can be only one event queue per thread, so if an event - * queue for the current thread already exists, this object is simply attached - * to the existing event queue. - */ -EventQueue::EventQueue() -{ -#ifndef VBOX_WITH_XPCOM - - mThreadId = GetCurrentThreadId(); - // force the system to create the message queue for the current thread - MSG msg; - PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); - - if (!DuplicateHandle(GetCurrentProcess(), - GetCurrentThread(), - GetCurrentProcess(), - &mhThread, - 0 /*dwDesiredAccess*/, - FALSE /*bInheritHandle*/, - DUPLICATE_SAME_ACCESS)) - mhThread = INVALID_HANDLE_VALUE; - -#else // VBOX_WITH_XPCOM - - mEQCreated = false; - mInterrupted = false; - - // Here we reference the global nsIEventQueueService instance and hold it - // until we're destroyed. This is necessary to keep NS_ShutdownXPCOM() away - // from calling StopAcceptingEvents() on all event queues upon destruction of - // nsIEventQueueService, and makes sense when, for some reason, this happens - // *before* we're able to send a NULL event to stop our event handler thread - // when doing unexpected cleanup caused indirectly by NS_ShutdownXPCOM() - // that is performing a global cleanup of everything. A good example of such - // situation is when NS_ShutdownXPCOM() is called while the VirtualBox component - // is still alive (because it is still referenced): eventually, it results in - // a VirtualBox::uninit() call from where it is already not possible to post - // NULL to the event thread (because it stopped accepting events). - - nsresult rc = NS_GetEventQueueService(getter_AddRefs(mEventQService)); - - if (NS_SUCCEEDED(rc)) - { - rc = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(mEventQ)); - if (rc == NS_ERROR_NOT_AVAILABLE) - { - rc = mEventQService->CreateThreadEventQueue(); - if (NS_SUCCEEDED(rc)) - { - mEQCreated = true; - rc = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, - getter_AddRefs(mEventQ)); - } - } - } - AssertComRC(rc); - -#endif // VBOX_WITH_XPCOM -} - -EventQueue::~EventQueue() -{ -#ifndef VBOX_WITH_XPCOM - if (mhThread != INVALID_HANDLE_VALUE) - { - CloseHandle(mhThread); - mhThread = INVALID_HANDLE_VALUE; - } -#else // VBOX_WITH_XPCOM - // process all pending events before destruction - if (mEventQ) - { - if (mEQCreated) - { - mEventQ->StopAcceptingEvents(); - mEventQ->ProcessPendingEvents(); - mEventQService->DestroyThreadEventQueue(); - } - mEventQ = nsnull; - mEventQService = nsnull; - } -#endif // VBOX_WITH_XPCOM -} - -/** - * Initializes the main event queue instance. - * @returns VBox status code. - * - * @remarks If you're using the rest of the COM/XPCOM glue library, - * com::Initialize() will take care of initializing and uninitializing - * the EventQueue class. If you don't call com::Initialize, you must - * make sure to call this method on the same thread that did the - * XPCOM initialization or we'll end up using the wrong main queue. - */ -/* static */ -int EventQueue::init() +EventQueue::EventQueue(void) + : mUserCnt(0), + mShutdown(false) { - Assert(sMainQueue == NULL); - Assert(RTThreadIsMain(RTThreadSelf())); - sMainQueue = new EventQueue(); - -#ifdef VBOX_WITH_XPCOM - /* Check that it actually is the main event queue, i.e. that - we're called on the right thread. */ - nsCOMPtr<nsIEventQueue> q; - nsresult rv = NS_GetMainEventQ(getter_AddRefs(q)); - Assert(NS_SUCCEEDED(rv)); - Assert(q == sMainQueue->mEventQ); - - /* Check that it's a native queue. */ - PRBool fIsNative = PR_FALSE; - rv = sMainQueue->mEventQ->IsQueueNative(&fIsNative); - Assert(NS_SUCCEEDED(rv) && fIsNative); -#endif // VBOX_WITH_XPCOM - - return VINF_SUCCESS; -} - -/** - * Uninitialize the global resources (i.e. the main event queue instance). - * @returns VINF_SUCCESS - */ -/* static */ -int EventQueue::uninit() -{ - if (sMainQueue) - { - /* Must process all events to make sure that no NULL event is left - * after this point. It would need to modify the state of sMainQueue. */ -#ifdef RT_OS_DARWIN /* Do not process the native runloop, the toolkit may not be ready for it. */ - sMainQueue->mEventQ->ProcessPendingEvents(); -#else - sMainQueue->processEventQueue(0); -#endif - delete sMainQueue; - sMainQueue = NULL; - } - return VINF_SUCCESS; -} + int rc = RTCritSectInit(&mCritSect); + AssertRC(rc); -/** - * Get main event queue instance. - * - * Depends on init() being called first. - */ -/* static */ -EventQueue* EventQueue::getMainEventQueue() -{ - return sMainQueue; + rc = RTSemEventCreate(&mSemEvent); + AssertRC(rc); } -#ifdef VBOX_WITH_XPCOM -# ifdef RT_OS_DARWIN -/** - * Wait for events and process them (Darwin). - * - * @retval VINF_SUCCESS - * @retval VERR_TIMEOUT - * @retval VERR_INTERRUPTED - * - * @param cMsTimeout How long to wait, or RT_INDEFINITE_WAIT. - */ -static int waitForEventsOnDarwin(RTMSINTERVAL cMsTimeout) +EventQueue::~EventQueue(void) { - /* - * Wait for the requested time, if we get a hit we do a poll to process - * any other pending messages. - * - * Note! About 1.0e10: According to the sources anything above 3.1556952e+9 - * means indefinite wait and 1.0e10 is what CFRunLoopRun() uses. - */ - CFTimeInterval rdTimeout = cMsTimeout == RT_INDEFINITE_WAIT ? 1e10 : (double)cMsTimeout / 1000; - OSStatus orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, rdTimeout, true /*returnAfterSourceHandled*/); - if (orc == kCFRunLoopRunHandledSource) - { - OSStatus orc2 = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, false /*returnAfterSourceHandled*/); - if ( orc2 == kCFRunLoopRunStopped - || orc2 == kCFRunLoopRunFinished) - orc = orc2; - } - if ( orc == 0 /*???*/ - || orc == kCFRunLoopRunHandledSource) - return VINF_SUCCESS; - if ( orc == kCFRunLoopRunStopped - || orc == kCFRunLoopRunFinished) - return VERR_INTERRUPTED; - AssertMsg(orc == kCFRunLoopRunTimedOut, ("Unexpected status code from CFRunLoopRunInMode: %#x", orc)); - return VERR_TIMEOUT; -} -# else // !RT_OS_DARWIN + int rc = RTCritSectDelete(&mCritSect); + AssertRC(rc); -/** - * Wait for events (generic XPCOM). - * - * @retval VINF_SUCCESS - * @retval VERR_TIMEOUT - * @retval VINF_INTERRUPTED - * @retval VERR_INTERNAL_ERROR_4 - * - * @param pQueue The queue to wait on. - * @param cMsTimeout How long to wait, or RT_INDEFINITE_WAIT. - */ -static int waitForEventsOnXPCOM(nsIEventQueue *pQueue, RTMSINTERVAL cMsTimeout) -{ - int fd = pQueue->GetEventQueueSelectFD(); - fd_set fdsetR; - FD_ZERO(&fdsetR); - FD_SET(fd, &fdsetR); - - fd_set fdsetE = fdsetR; - - struct timeval tv = {0,0}; - struct timeval *ptv; - if (cMsTimeout == RT_INDEFINITE_WAIT) - ptv = NULL; - else - { - tv.tv_sec = cMsTimeout / 1000; - tv.tv_usec = (cMsTimeout % 1000) * 1000; - ptv = &tv; - } + rc = RTSemEventDestroy(mSemEvent); + AssertRC(rc); - int rc = select(fd + 1, &fdsetR, NULL, &fdsetE, ptv); - if (rc > 0) - rc = VINF_SUCCESS; - else if (rc == 0) - rc = VERR_TIMEOUT; - else if (errno == EINTR) - rc = VINF_INTERRUPTED; - else + EventQueueListIterator it = mEvents.begin(); + while (it != mEvents.end()) { - static uint32_t s_ErrorCount = 0; - if (s_ErrorCount < 500) - { - LogRel(("waitForEventsOnXPCOM rc=%d errno=%d\n", rc, errno)); - ++s_ErrorCount; - } - - AssertMsgFailed(("rc=%d errno=%d\n", rc, errno)); - rc = VERR_INTERNAL_ERROR_4; + (*it)->Release(); + it = mEvents.erase(it); } - return rc; } -# endif // !RT_OS_DARWIN -#endif // VBOX_WITH_XPCOM - -#ifndef VBOX_WITH_XPCOM - -/** - * Dispatch a message on Windows. - * - * This will pick out our events and handle them specially. - * - * @returns @a rc or VERR_INTERRUPTED (WM_QUIT or NULL msg). - * @param pMsg The message to dispatch. - * @param rc The current status code. - */ -/*static*/ -int EventQueue::dispatchMessageOnWindows(MSG const *pMsg, int rc) -{ - /* - * Check for and dispatch our events. - */ - if ( pMsg->hwnd == NULL - && pMsg->message == WM_USER) - { - if (pMsg->lParam == EVENTQUEUE_WIN_LPARAM_MAGIC) - { - Event *pEvent = (Event *)pMsg->wParam; - if (pEvent) - { - pEvent->handler(); - delete pEvent; - } - else - rc = VERR_INTERRUPTED; - return rc; - } - AssertMsgFailed(("lParam=%p wParam=%p\n", pMsg->lParam, pMsg->wParam)); - } - - /* - * Check for the quit message and dispatch the message the normal way. - */ - if (pMsg->message == WM_QUIT) - rc = VERR_INTERRUPTED; - TranslateMessage(pMsg); - DispatchMessage(pMsg); - - return rc; -} - - -/** - * Process pending events (Windows). - * - * @retval VINF_SUCCESS - * @retval VERR_TIMEOUT - * @retval VERR_INTERRUPTED. - */ -static int processPendingEvents(void) -{ - int rc = VERR_TIMEOUT; - MSG Msg; - if (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE)) - { - rc = VINF_SUCCESS; - do - rc = EventQueue::dispatchMessageOnWindows(&Msg, rc); - while (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE)); - } - return rc; -} - -#else // VBOX_WITH_XPCOM - -/** - * Process pending XPCOM events. - * @param pQueue The queue to process events on. - * @retval VINF_SUCCESS - * @retval VERR_TIMEOUT - * @retval VERR_INTERRUPTED (darwin only) - * @retval VERR_INTERNAL_ERROR_2 - */ -static int processPendingEvents(nsIEventQueue *pQueue) -{ - /* ProcessPendingEvents doesn't report back what it did, so check here. */ - PRBool fHasEvents = PR_FALSE; - nsresult hr = pQueue->PendingEvents(&fHasEvents); - if (NS_FAILED(hr)) - return VERR_INTERNAL_ERROR_2; - - /* Process pending events. */ - int rc = VINF_SUCCESS; - if (fHasEvents) - pQueue->ProcessPendingEvents(); - else - rc = VERR_TIMEOUT; - -# ifdef RT_OS_DARWIN - /* Process pending native events. */ - int rc2 = waitForEventsOnDarwin(0); - if (rc == VERR_TIMEOUT || rc2 == VERR_INTERRUPTED) - rc = rc2; -# endif - - return rc; -} - -#endif // VBOX_WITH_XPCOM - /** * Process events pending on this event queue, and wait up to given timeout, if * nothing is available. @@ -489,80 +86,92 @@ static int processPendingEvents(nsIEventQueue *pQueue) */ int EventQueue::processEventQueue(RTMSINTERVAL cMsTimeout) { - int rc; - CHECK_THREAD_RET(VERR_INVALID_CONTEXT); - -#ifdef VBOX_WITH_XPCOM - /* - * Process pending events, if none are available and we're not in a - * poll call, wait for some to appear. (We have to be a little bit - * careful after waiting for the events since Darwin will process - * them as part of the wait, while the XPCOM case will not.) - * - * Note! Unfortunately, WaitForEvent isn't interruptible with Ctrl-C, - * while select() is. So we cannot use it for indefinite waits. - */ - rc = processPendingEvents(mEventQ); - if ( rc == VERR_TIMEOUT - && cMsTimeout > 0) + size_t cNumEvents; + int rc = RTCritSectEnter(&mCritSect); + if (RT_SUCCESS(rc)) { -# ifdef RT_OS_DARWIN - /** @todo check how Ctrl-C works on Darwin. */ - rc = waitForEventsOnDarwin(cMsTimeout); - if (rc == VERR_TIMEOUT) - rc = processPendingEvents(mEventQ); -# else // !RT_OS_DARWIN - rc = waitForEventsOnXPCOM(mEventQ, cMsTimeout); - if ( RT_SUCCESS(rc) - || rc == VERR_TIMEOUT) - rc = processPendingEvents(mEventQ); -# endif // !RT_OS_DARWIN - } + if (mUserCnt == 0) /* No concurrent access allowed. */ + { + mUserCnt++; - if ( ( RT_SUCCESS(rc) - || rc == VERR_INTERRUPTED - || rc == VERR_TIMEOUT) - && mInterrupted) - { - mInterrupted = false; - rc = VERR_INTERRUPTED; - } + cNumEvents = mEvents.size(); + if (!cNumEvents) + { + int rc2 = RTCritSectLeave(&mCritSect); + AssertRC(rc2); -#else // !VBOX_WITH_XPCOM - if (cMsTimeout == RT_INDEFINITE_WAIT) - { - BOOL fRet; - MSG Msg; - rc = VINF_SUCCESS; - while ( rc != VERR_INTERRUPTED - && (fRet = GetMessage(&Msg, NULL /*hWnd*/, WM_USER, WM_USER)) - && fRet != -1) - rc = EventQueue::dispatchMessageOnWindows(&Msg, rc); - if (fRet == 0) - rc = VERR_INTERRUPTED; - else if (fRet == -1) - rc = RTErrConvertFromWin32(GetLastError()); + rc = RTSemEventWaitNoResume(mSemEvent, cMsTimeout); + + rc2 = RTCritSectEnter(&mCritSect); + AssertRC(rc2); + + if (RT_SUCCESS(rc)) + { + if (mShutdown) + rc = VERR_INTERRUPTED; + cNumEvents = mEvents.size(); + } + } + + if (RT_SUCCESS(rc)) + rc = processPendingEvents(cNumEvents); + + Assert(mUserCnt); + mUserCnt--; + } + else + rc = VERR_WRONG_ORDER; + + int rc2 = RTCritSectLeave(&mCritSect); + if (RT_SUCCESS(rc)) + rc = rc2; } - else + + Assert(rc != VERR_TIMEOUT || cMsTimeout != RT_INDEFINITE_WAIT); + return rc; +} + +/** + * Processes all pending events in the queue at the time of + * calling. Note: Does no initial locking, must be done by the + * caller! + * + * @return IPRT status code. + */ +int EventQueue::processPendingEvents(size_t cNumEvents) +{ + if (!cNumEvents) /* Nothing to process? Bail out early. */ + return VINF_SUCCESS; + + int rc = VINF_SUCCESS; + + EventQueueListIterator it = mEvents.begin(); + for (size_t i = 0; + i < cNumEvents + && it != mEvents.end(); i++) { - rc = processPendingEvents(); - if ( rc == VERR_TIMEOUT - && cMsTimeout != 0) + Event *pEvent = *it; + AssertPtr(pEvent); + + mEvents.erase(it); + + int rc2 = RTCritSectLeave(&mCritSect); + AssertRC(rc2); + + pEvent->handler(); + pEvent->Release(); + + rc2 = RTCritSectEnter(&mCritSect); + AssertRC(rc2); + + it = mEvents.begin(); + if (mShutdown) { - DWORD rcW = MsgWaitForMultipleObjects(1, - &mhThread, - TRUE /*fWaitAll*/, - cMsTimeout, - QS_ALLINPUT); - AssertMsgReturn(rcW == WAIT_TIMEOUT || rcW == WAIT_OBJECT_0, - ("%d\n", rcW), - VERR_INTERNAL_ERROR_4); - rc = processPendingEvents(); + rc = VERR_INTERRUPTED; + break; } } -#endif // !VBOX_WITH_XPCOM - Assert(rc != VERR_TIMEOUT || cMsTimeout != RT_INDEFINITE_WAIT); return rc; } @@ -573,13 +182,11 @@ int EventQueue::processEventQueue(RTMSINTERVAL cMsTimeout) * * @returns VBox status code. */ -int EventQueue::interruptEventQueueProcessing() +int EventQueue::interruptEventQueueProcessing(void) { - /* Send a NULL event. This event will be picked up and handled specially - * both for XPCOM and Windows. It is the responsibility of the caller to - * take care of not running the loop again in a way which will hang. */ - postEvent(NULL); - return VINF_SUCCESS; + ASMAtomicWriteBool(&mShutdown, true); + + return RTSemEventSignal(mSemEvent); } /** @@ -588,39 +195,52 @@ int EventQueue::interruptEventQueueProcessing() * @param event the event to post, must be allocated using |new| * @return TRUE if successful and false otherwise */ -BOOL EventQueue::postEvent(Event *event) +BOOL EventQueue::postEvent(Event *pEvent) { -#ifndef VBOX_WITH_XPCOM - /* Note! The event == NULL case is duplicated in vboxapi/PlatformMSCOM::interruptWaitEvents(). */ - return PostThreadMessage(mThreadId, WM_USER, (WPARAM)event, EVENTQUEUE_WIN_LPARAM_MAGIC); - -#else // VBOX_WITH_XPCOM - - if (!mEventQ) - return FALSE; + int rc = RTCritSectEnter(&mCritSect); + if (RT_SUCCESS(rc)) + { + try + { + if (pEvent) + { + pEvent->AddRef(); + mEvents.push_back(pEvent); + } + else /* No locking, since we're already in our crit sect. */ + mShutdown = true; - MyPLEvent *ev = new MyPLEvent(event); - mEventQ->InitEvent(ev, this, com::EventQueue::plEventHandler, - com::EventQueue::plEventDestructor); - HRESULT rc = mEventQ->PostEvent(ev); - return NS_SUCCEEDED(rc); + size_t cEvents = mEvents.size(); + if (cEvents > _1K) /** @todo Make value configurable? */ + { + static int s_cBitchedAboutLotEvents = 0; + if (s_cBitchedAboutLotEvents < 10) + LogRel(("Warning: Event queue received lots of events (%zu), expect delayed event handling (%d/10)\n", + cEvents, ++s_cBitchedAboutLotEvents)); + } -#endif // VBOX_WITH_XPCOM -} + /* Leave critical section before signalling event. */ + rc = RTCritSectLeave(&mCritSect); + if (RT_SUCCESS(rc)) + { + int rc2 = RTSemEventSignal(mSemEvent); + AssertRC(rc2); + } + } + catch (std::bad_alloc &ba) + { + NOREF(ba); + rc = VERR_NO_MEMORY; + } + if (RT_FAILURE(rc)) + { + int rc2 = RTCritSectLeave(&mCritSect); + AssertRC(rc2); + } + } -/** - * Get select()'able selector for this event queue. - * This will return -1 on platforms and queue variants not supporting such - * functionality. - */ -int EventQueue::getSelectFD() -{ -#ifdef VBOX_WITH_XPCOM - return mEventQ->GetEventQueueSelectFD(); -#else - return -1; -#endif + return RT_SUCCESS(rc) ? TRUE : FALSE; } } diff --git a/src/VBox/Main/glue/NativeEventQueue.cpp b/src/VBox/Main/glue/NativeEventQueue.cpp new file mode 100644 index 00000000..23420f20 --- /dev/null +++ b/src/VBox/Main/glue/NativeEventQueue.cpp @@ -0,0 +1,655 @@ +/* $Id: NativeEventQueue.cpp $ */ +/** @file + * MS COM / XPCOM Abstraction Layer: + * Main event queue class declaration + */ + +/* + * Copyright (C) 2006-2010 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +#include "VBox/com/NativeEventQueue.h" + +#include <new> /* For bad_alloc. */ + +#ifdef RT_OS_DARWIN +# include <CoreFoundation/CFRunLoop.h> +#endif + +#if defined(VBOX_WITH_XPCOM) && !defined(RT_OS_DARWIN) && !defined(RT_OS_OS2) +# define USE_XPCOM_QUEUE +#endif + +#include <iprt/err.h> +#include <iprt/time.h> +#include <iprt/thread.h> +#include <iprt/log.h> +#ifdef USE_XPCOM_QUEUE +# include <errno.h> +#endif + +namespace com +{ + +// NativeEventQueue class +//////////////////////////////////////////////////////////////////////////////// + +#ifndef VBOX_WITH_XPCOM + +# define CHECK_THREAD_RET(ret) \ + do { \ + AssertMsg(GetCurrentThreadId() == mThreadId, ("Must be on event queue thread!")); \ + if (GetCurrentThreadId() != mThreadId) \ + return ret; \ + } while (0) + +/** Magic LPARAM value for the WM_USER messages that we're posting. + * @remarks This magic value is duplicated in + * vboxapi/PlatformMSCOM::interruptWaitEvents(). */ +#define EVENTQUEUE_WIN_LPARAM_MAGIC UINT32_C(0xf241b819) + + +#else // VBOX_WITH_XPCOM + +# define CHECK_THREAD_RET(ret) \ + do { \ + if (!mEventQ) \ + return ret; \ + BOOL isOnCurrentThread = FALSE; \ + mEventQ->IsOnCurrentThread(&isOnCurrentThread); \ + AssertMsg(isOnCurrentThread, ("Must be on event queue thread!")); \ + if (!isOnCurrentThread) \ + return ret; \ + } while (0) + +#endif // VBOX_WITH_XPCOM + +/** Pointer to the main event queue. */ +NativeEventQueue *NativeEventQueue::sMainQueue = NULL; + + +#ifdef VBOX_WITH_XPCOM + +struct MyPLEvent : public PLEvent +{ + MyPLEvent(NativeEvent *e) : event(e) {} + NativeEvent *event; +}; + +/* static */ +void *PR_CALLBACK com::NativeEventQueue::plEventHandler(PLEvent *self) +{ + NativeEvent *ev = ((MyPLEvent *)self)->event; + if (ev) + ev->handler(); + else + { + NativeEventQueue *eq = (NativeEventQueue *)self->owner; + Assert(eq); + eq->mInterrupted = true; + } + return NULL; +} + +/* static */ +void PR_CALLBACK com::NativeEventQueue::plEventDestructor(PLEvent *self) +{ + NativeEvent *ev = ((MyPLEvent *)self)->event; + if (ev) + delete ev; + delete self; +} + +#endif // VBOX_WITH_XPCOM + +/** + * Constructs an event queue for the current thread. + * + * Currently, there can be only one event queue per thread, so if an event + * queue for the current thread already exists, this object is simply attached + * to the existing event queue. + */ +NativeEventQueue::NativeEventQueue() +{ +#ifndef VBOX_WITH_XPCOM + + mThreadId = GetCurrentThreadId(); + // force the system to create the message queue for the current thread + MSG msg; + PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + + if (!DuplicateHandle(GetCurrentProcess(), + GetCurrentThread(), + GetCurrentProcess(), + &mhThread, + 0 /*dwDesiredAccess*/, + FALSE /*bInheritHandle*/, + DUPLICATE_SAME_ACCESS)) + mhThread = INVALID_HANDLE_VALUE; + +#else // VBOX_WITH_XPCOM + + mEQCreated = false; + mInterrupted = false; + + // Here we reference the global nsIEventQueueService instance and hold it + // until we're destroyed. This is necessary to keep NS_ShutdownXPCOM() away + // from calling StopAcceptingEvents() on all event queues upon destruction of + // nsIEventQueueService, and makes sense when, for some reason, this happens + // *before* we're able to send a NULL event to stop our event handler thread + // when doing unexpected cleanup caused indirectly by NS_ShutdownXPCOM() + // that is performing a global cleanup of everything. A good example of such + // situation is when NS_ShutdownXPCOM() is called while the VirtualBox component + // is still alive (because it is still referenced): eventually, it results in + // a VirtualBox::uninit() call from where it is already not possible to post + // NULL to the event thread (because it stopped accepting events). + + nsresult rc = NS_GetEventQueueService(getter_AddRefs(mEventQService)); + + if (NS_SUCCEEDED(rc)) + { + rc = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, + getter_AddRefs(mEventQ)); + if (rc == NS_ERROR_NOT_AVAILABLE) + { + rc = mEventQService->CreateThreadEventQueue(); + if (NS_SUCCEEDED(rc)) + { + mEQCreated = true; + rc = mEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, + getter_AddRefs(mEventQ)); + } + } + } + AssertComRC(rc); + +#endif // VBOX_WITH_XPCOM +} + +NativeEventQueue::~NativeEventQueue() +{ +#ifndef VBOX_WITH_XPCOM + if (mhThread != INVALID_HANDLE_VALUE) + { + CloseHandle(mhThread); + mhThread = INVALID_HANDLE_VALUE; + } +#else // VBOX_WITH_XPCOM + // process all pending events before destruction + if (mEventQ) + { + if (mEQCreated) + { + mEventQ->StopAcceptingEvents(); + mEventQ->ProcessPendingEvents(); + mEventQService->DestroyThreadEventQueue(); + } + mEventQ = nsnull; + mEventQService = nsnull; + } +#endif // VBOX_WITH_XPCOM +} + +/** + * Initializes the main event queue instance. + * @returns VBox status code. + * + * @remarks If you're using the rest of the COM/XPCOM glue library, + * com::Initialize() will take care of initializing and uninitializing + * the NativeEventQueue class. If you don't call com::Initialize, you must + * make sure to call this method on the same thread that did the + * XPCOM initialization or we'll end up using the wrong main queue. + */ +/* static */ +int NativeEventQueue::init() +{ + Assert(sMainQueue == NULL); + Assert(RTThreadIsMain(RTThreadSelf())); + + try + { + sMainQueue = new NativeEventQueue(); + AssertPtr(sMainQueue); +#ifdef VBOX_WITH_XPCOM + /* Check that it actually is the main event queue, i.e. that + we're called on the right thread. */ + nsCOMPtr<nsIEventQueue> q; + nsresult rv = NS_GetMainEventQ(getter_AddRefs(q)); + AssertComRCReturn(rv, VERR_INVALID_POINTER); + Assert(q == sMainQueue->mEventQ); + + /* Check that it's a native queue. */ + PRBool fIsNative = PR_FALSE; + rv = sMainQueue->mEventQ->IsQueueNative(&fIsNative); + Assert(NS_SUCCEEDED(rv) && fIsNative); +#endif // VBOX_WITH_XPCOM + } + catch (std::bad_alloc &ba) + { + NOREF(ba); + return VERR_NO_MEMORY; + } + + return VINF_SUCCESS; +} + +/** + * Uninitialize the global resources (i.e. the main event queue instance). + * @returns VINF_SUCCESS + */ +/* static */ +int NativeEventQueue::uninit() +{ + if (sMainQueue) + { + /* Must process all events to make sure that no NULL event is left + * after this point. It would need to modify the state of sMainQueue. */ +#ifdef RT_OS_DARWIN /* Do not process the native runloop, the toolkit may not be ready for it. */ + sMainQueue->mEventQ->ProcessPendingEvents(); +#else + sMainQueue->processEventQueue(0); +#endif + delete sMainQueue; + sMainQueue = NULL; + } + return VINF_SUCCESS; +} + +/** + * Get main event queue instance. + * + * Depends on init() being called first. + */ +/* static */ +NativeEventQueue* NativeEventQueue::getMainEventQueue() +{ + return sMainQueue; +} + +#ifdef VBOX_WITH_XPCOM +# ifdef RT_OS_DARWIN +/** + * Wait for events and process them (Darwin). + * + * @retval VINF_SUCCESS + * @retval VERR_TIMEOUT + * @retval VERR_INTERRUPTED + * + * @param cMsTimeout How long to wait, or RT_INDEFINITE_WAIT. + */ +static int waitForEventsOnDarwin(RTMSINTERVAL cMsTimeout) +{ + /* + * Wait for the requested time, if we get a hit we do a poll to process + * any other pending messages. + * + * Note! About 1.0e10: According to the sources anything above 3.1556952e+9 + * means indefinite wait and 1.0e10 is what CFRunLoopRun() uses. + */ + CFTimeInterval rdTimeout = cMsTimeout == RT_INDEFINITE_WAIT ? 1e10 : (double)cMsTimeout / 1000; + OSStatus orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, rdTimeout, true /*returnAfterSourceHandled*/); + if (orc == kCFRunLoopRunHandledSource) + { + OSStatus orc2 = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, false /*returnAfterSourceHandled*/); + if ( orc2 == kCFRunLoopRunStopped + || orc2 == kCFRunLoopRunFinished) + orc = orc2; + } + if ( orc == 0 /*???*/ + || orc == kCFRunLoopRunHandledSource) + return VINF_SUCCESS; + if ( orc == kCFRunLoopRunStopped + || orc == kCFRunLoopRunFinished) + return VERR_INTERRUPTED; + AssertMsg(orc == kCFRunLoopRunTimedOut, ("Unexpected status code from CFRunLoopRunInMode: %#x", orc)); + return VERR_TIMEOUT; +} +# else // !RT_OS_DARWIN + +/** + * Wait for events (generic XPCOM). + * + * @retval VINF_SUCCESS + * @retval VERR_TIMEOUT + * @retval VINF_INTERRUPTED + * @retval VERR_INTERNAL_ERROR_4 + * + * @param pQueue The queue to wait on. + * @param cMsTimeout How long to wait, or RT_INDEFINITE_WAIT. + */ +static int waitForEventsOnXPCOM(nsIEventQueue *pQueue, RTMSINTERVAL cMsTimeout) +{ + int fd = pQueue->GetEventQueueSelectFD(); + fd_set fdsetR; + FD_ZERO(&fdsetR); + FD_SET(fd, &fdsetR); + + fd_set fdsetE = fdsetR; + + struct timeval tv = {0,0}; + struct timeval *ptv; + if (cMsTimeout == RT_INDEFINITE_WAIT) + ptv = NULL; + else + { + tv.tv_sec = cMsTimeout / 1000; + tv.tv_usec = (cMsTimeout % 1000) * 1000; + ptv = &tv; + } + + int rc = select(fd + 1, &fdsetR, NULL, &fdsetE, ptv); + if (rc > 0) + rc = VINF_SUCCESS; + else if (rc == 0) + rc = VERR_TIMEOUT; + else if (errno == EINTR) + rc = VINF_INTERRUPTED; + else + { + static uint32_t s_ErrorCount = 0; + if (s_ErrorCount < 500) + { + LogRel(("waitForEventsOnXPCOM rc=%d errno=%d\n", rc, errno)); + ++s_ErrorCount; + } + + AssertMsgFailed(("rc=%d errno=%d\n", rc, errno)); + rc = VERR_INTERNAL_ERROR_4; + } + return rc; +} + +# endif // !RT_OS_DARWIN +#endif // VBOX_WITH_XPCOM + +#ifndef VBOX_WITH_XPCOM + +/** + * Dispatch a message on Windows. + * + * This will pick out our events and handle them specially. + * + * @returns @a rc or VERR_INTERRUPTED (WM_QUIT or NULL msg). + * @param pMsg The message to dispatch. + * @param rc The current status code. + */ +/*static*/ +int NativeEventQueue::dispatchMessageOnWindows(MSG const *pMsg, int rc) +{ + /* + * Check for and dispatch our events. + */ + if ( pMsg->hwnd == NULL + && pMsg->message == WM_USER) + { + if (pMsg->lParam == EVENTQUEUE_WIN_LPARAM_MAGIC) + { + NativeEvent *pEvent = (NativeEvent *)pMsg->wParam; + if (pEvent) + { + pEvent->handler(); + delete pEvent; + } + else + rc = VERR_INTERRUPTED; + return rc; + } + AssertMsgFailed(("lParam=%p wParam=%p\n", pMsg->lParam, pMsg->wParam)); + } + + /* + * Check for the quit message and dispatch the message the normal way. + */ + if (pMsg->message == WM_QUIT) + rc = VERR_INTERRUPTED; + TranslateMessage(pMsg); + DispatchMessage(pMsg); + + return rc; +} + + +/** + * Process pending events (Windows). + * + * @retval VINF_SUCCESS + * @retval VERR_TIMEOUT + * @retval VERR_INTERRUPTED. + */ +static int processPendingEvents(void) +{ + int rc = VERR_TIMEOUT; + MSG Msg; + if (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE)) + { + rc = VINF_SUCCESS; + do + rc = NativeEventQueue::dispatchMessageOnWindows(&Msg, rc); + while (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE)); + } + return rc; +} + +#else // VBOX_WITH_XPCOM + +/** + * Process pending XPCOM events. + * @param pQueue The queue to process events on. + * @retval VINF_SUCCESS + * @retval VERR_TIMEOUT + * @retval VERR_INTERRUPTED (darwin only) + * @retval VERR_INTERNAL_ERROR_2 + */ +static int processPendingEvents(nsIEventQueue *pQueue) +{ + /* ProcessPendingEvents doesn't report back what it did, so check here. */ + PRBool fHasEvents = PR_FALSE; + nsresult hr = pQueue->PendingEvents(&fHasEvents); + if (NS_FAILED(hr)) + return VERR_INTERNAL_ERROR_2; + + /* Process pending events. */ + int rc = VINF_SUCCESS; + if (fHasEvents) + pQueue->ProcessPendingEvents(); + else + rc = VERR_TIMEOUT; + +# ifdef RT_OS_DARWIN + /* Process pending native events. */ + int rc2 = waitForEventsOnDarwin(0); + if (rc == VERR_TIMEOUT || rc2 == VERR_INTERRUPTED) + rc = rc2; +# endif + + return rc; +} + +#endif // VBOX_WITH_XPCOM + +/** + * Process events pending on this event queue, and wait up to given timeout, if + * nothing is available. + * + * Must be called on same thread this event queue was created on. + * + * @param cMsTimeout The timeout specified as milliseconds. Use + * RT_INDEFINITE_WAIT to wait till an event is posted on the + * queue. + * + * @returns VBox status code + * @retval VINF_SUCCESS if one or more messages was processed. + * @retval VERR_TIMEOUT if cMsTimeout expired. + * @retval VERR_INVALID_CONTEXT if called on the wrong thread. + * @retval VERR_INTERRUPTED if interruptEventQueueProcessing was called. + * On Windows will also be returned when WM_QUIT is encountered. + * On Darwin this may also be returned when the native queue is + * stopped or destroyed/finished. + * @retval VINF_INTERRUPTED if the native system call was interrupted by a + * an asynchronous event delivery (signal) or just felt like returning + * out of bounds. On darwin it will also be returned if the queue is + * stopped. + */ +int NativeEventQueue::processEventQueue(RTMSINTERVAL cMsTimeout) +{ + int rc; + CHECK_THREAD_RET(VERR_INVALID_CONTEXT); + +#ifdef VBOX_WITH_XPCOM + /* + * Process pending events, if none are available and we're not in a + * poll call, wait for some to appear. (We have to be a little bit + * careful after waiting for the events since Darwin will process + * them as part of the wait, while the XPCOM case will not.) + * + * Note! Unfortunately, WaitForEvent isn't interruptible with Ctrl-C, + * while select() is. So we cannot use it for indefinite waits. + */ + rc = processPendingEvents(mEventQ); + if ( rc == VERR_TIMEOUT + && cMsTimeout > 0) + { +# ifdef RT_OS_DARWIN + /** @todo check how Ctrl-C works on Darwin. */ + rc = waitForEventsOnDarwin(cMsTimeout); + if (rc == VERR_TIMEOUT) + rc = processPendingEvents(mEventQ); +# else // !RT_OS_DARWIN + rc = waitForEventsOnXPCOM(mEventQ, cMsTimeout); + if ( RT_SUCCESS(rc) + || rc == VERR_TIMEOUT) + rc = processPendingEvents(mEventQ); +# endif // !RT_OS_DARWIN + } + + if ( ( RT_SUCCESS(rc) + || rc == VERR_INTERRUPTED + || rc == VERR_TIMEOUT) + && mInterrupted) + { + mInterrupted = false; + rc = VERR_INTERRUPTED; + } + +#else // !VBOX_WITH_XPCOM + if (cMsTimeout == RT_INDEFINITE_WAIT) + { + BOOL fRet; + MSG Msg; + rc = VINF_SUCCESS; + while ( rc != VERR_INTERRUPTED + && (fRet = GetMessage(&Msg, NULL /*hWnd*/, WM_USER, WM_USER)) + && fRet != -1) + rc = NativeEventQueue::dispatchMessageOnWindows(&Msg, rc); + if (fRet == 0) + rc = VERR_INTERRUPTED; + else if (fRet == -1) + rc = RTErrConvertFromWin32(GetLastError()); + } + else + { + rc = processPendingEvents(); + if ( rc == VERR_TIMEOUT + && cMsTimeout != 0) + { + DWORD rcW = MsgWaitForMultipleObjects(1, + &mhThread, + TRUE /*fWaitAll*/, + cMsTimeout, + QS_ALLINPUT); + AssertMsgReturn(rcW == WAIT_TIMEOUT || rcW == WAIT_OBJECT_0, + ("%d\n", rcW), + VERR_INTERNAL_ERROR_4); + rc = processPendingEvents(); + } + } +#endif // !VBOX_WITH_XPCOM + + Assert(rc != VERR_TIMEOUT || cMsTimeout != RT_INDEFINITE_WAIT); + return rc; +} + +/** + * Interrupt thread waiting on event queue processing. + * + * Can be called on any thread. + * + * @returns VBox status code. + */ +int NativeEventQueue::interruptEventQueueProcessing() +{ + /* Send a NULL event. This event will be picked up and handled specially + * both for XPCOM and Windows. It is the responsibility of the caller to + * take care of not running the loop again in a way which will hang. */ + postEvent(NULL); + return VINF_SUCCESS; +} + +/** + * Posts an event to this event loop asynchronously. + * + * @param event the event to post, must be allocated using |new| + * @return TRUE if successful and false otherwise + */ +BOOL NativeEventQueue::postEvent(NativeEvent *pEvent) +{ +#ifndef VBOX_WITH_XPCOM + /* Note! The event == NULL case is duplicated in vboxapi/PlatformMSCOM::interruptWaitEvents(). */ + BOOL fRc = PostThreadMessage(mThreadId, WM_USER, (WPARAM)pEvent, EVENTQUEUE_WIN_LPARAM_MAGIC); + if (!fRc) + { + static int s_cBitchedAboutFullNativeEventQueue = 0; + if ( GetLastError() == ERROR_NOT_ENOUGH_QUOTA + && s_cBitchedAboutFullNativeEventQueue < 10) + LogRel(("Warning: Asynchronous event queue (%p, thread %RI32) full, event (%p) not delivered (%d/10)\n", + this, mThreadId, pEvent, ++s_cBitchedAboutFullNativeEventQueue)); + else + AssertFailed(); + } + return fRc; +#else // VBOX_WITH_XPCOM + if (!mEventQ) + return FALSE; + + try + { + MyPLEvent *pMyEvent = new MyPLEvent(pEvent); + mEventQ->InitEvent(pMyEvent, this, com::NativeEventQueue::plEventHandler, + com::NativeEventQueue::plEventDestructor); + HRESULT rc = mEventQ->PostEvent(pMyEvent); + return NS_SUCCEEDED(rc); + } + catch (std::bad_alloc &ba) + { + AssertMsgFailed(("Out of memory while allocating memory for event=%p: %s\n", + pEvent, ba.what())); + } + + return FALSE; +#endif // VBOX_WITH_XPCOM +} + +/** + * Get select()'able selector for this event queue. + * This will return -1 on platforms and queue variants not supporting such + * functionality. + */ +int NativeEventQueue::getSelectFD() +{ +#ifdef VBOX_WITH_XPCOM + return mEventQ->GetEventQueueSelectFD(); +#else + return -1; +#endif +} + +} +/* namespace com */ diff --git a/src/VBox/Main/glue/com.cpp b/src/VBox/Main/glue/com.cpp index f2252662..66ca1525 100644 --- a/src/VBox/Main/glue/com.cpp +++ b/src/VBox/Main/glue/com.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2005-2012 Oracle Corporation + * Copyright (C) 2005-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -54,10 +54,25 @@ #include <VBox/err.h> #include <VBox/version.h> +#if !defined(RT_OS_DARWIN) && !defined(RT_OS_WINDOWS) +char szXdgConfigHome[RTPATH_MAX] = ""; +#endif + +/** + * Possible locations for the VirtualBox user configuration folder, + * listed from oldest (as in legacy) to newest. These can be either + * absolute or relative to the home directory. We use the first entry + * of the list which corresponds to a real folder on storage, or + * create a folder corresponding to the last in the list (the least + * legacy) if none do. + */ +const char *const apcszUserHome[] = #ifdef RT_OS_DARWIN -# define VBOX_USER_HOME_SUFFIX "Library/VirtualBox" +{ "Library/VirtualBox" }; +#elif defined RT_OS_WINDOWS +{ ".VirtualBox" }; #else -# define VBOX_USER_HOME_SUFFIX ".VirtualBox" +{ ".VirtualBox", szXdgConfigHome }; #endif #include "Logging.h" @@ -181,6 +196,24 @@ HRESULT GlueCreateInstance(const CLSID &clsid, #endif // VBOX_WITH_XPCOM +static int composeHomePath(char *aDir, size_t aDirLen, + const char *pcszBase) +{ + int vrc; + if (RTPathStartsWithRoot(pcszBase)) + vrc = RTStrCopy(aDir, aDirLen, pcszBase); + else + { + /* compose the config directory (full path) */ + /** @todo r=bird: RTPathUserHome doesn't necessarily return a + * full (abs) path like the comment above seems to indicate. */ + vrc = RTPathUserHome(aDir, aDirLen); + if (RT_SUCCESS(vrc)) + vrc = RTPathAppend(aDir, aDirLen, pcszBase); + } + return vrc; +} + int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir) { AssertReturn(aDir, VERR_INVALID_POINTER); @@ -193,6 +226,7 @@ int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir) int vrc = RTEnvGetEx(RTENV_DEFAULT, "VBOX_USER_HOME", szTmp, sizeof(szTmp), NULL); if (RT_SUCCESS(vrc) || vrc == VERR_ENV_VAR_NOT_FOUND) { + bool fFound = false; if (RT_SUCCESS(vrc)) { /* get the full path name */ @@ -200,17 +234,37 @@ int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir) } else { - /* compose the config directory (full path) */ - /** @todo r=bird: RTPathUserHome doesn't necessarily return a full (abs) path - * like the comment above seems to indicate. */ - vrc = RTPathUserHome(aDir, aDirLen); - if (RT_SUCCESS(vrc)) - vrc = RTPathAppend(aDir, aDirLen, VBOX_USER_HOME_SUFFIX); +#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_DARWIN) + const char *pcszConfigHome = RTEnvGet("XDG_CONFIG_HOME"); + if (pcszConfigHome && pcszConfigHome[0]) + { + vrc = RTStrCopy(szXdgConfigHome, + sizeof(szXdgConfigHome), + pcszConfigHome); + if (RT_SUCCESS(vrc)) + vrc = RTPathAppend(szXdgConfigHome, + sizeof(szXdgConfigHome), + "VirtualBox"); + } + else + vrc = RTStrCopy(szXdgConfigHome, + sizeof(szXdgConfigHome), + ".config/VirtualBox"); +#endif + for (unsigned i = 0; i < RT_ELEMENTS(apcszUserHome); ++i) + { + vrc = composeHomePath(aDir, aDirLen, apcszUserHome[i]); + if (RTDirExists(aDir)) + { + fFound = true; + break; + } + } } /* ensure the home directory exists */ if (RT_SUCCESS(vrc)) - if (!RTDirExists(aDir) && fCreateDir) + if (!fFound && fCreateDir) vrc = RTDirCreateFullPath(aDir, 0700); } @@ -242,6 +296,7 @@ static void vboxHeaderFooter(PRTLOGGER pReleaseLogger, RTLOGPHASE enmPhase, PFNR g_pszLogEntity, VBOX_VERSION_STRING, RTBldCfgRevision(), RTBldCfgTargetDotArch(), __DATE__, __TIME__, szTmp); + pfnLog(pReleaseLogger, "Build Type: %s\n", KBUILD_TYPE); int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pReleaseLogger, "OS Product: %s\n", szTmp); @@ -320,7 +375,7 @@ int VBoxLogRelCreate(const char *pcszEntity, const char *pcszLogFile, fFlags |= RTLOGFLAGS_USECRLF; #endif g_pszLogEntity = pcszEntity; - int vrc = RTLogCreateEx(&pReleaseLogger, fFlags, "all all.restrict default.unrestricted", + int vrc = RTLogCreateEx(&pReleaseLogger, fFlags, pcszGroupSettings, pcszEnvVarBase, RT_ELEMENTS(s_apszGroups), s_apszGroups, fDestFlags, vboxHeaderFooter, cHistory, uHistoryFileSize, uHistoryFileTime, pszError, cbError, pcszLogFile); diff --git a/src/VBox/Main/glue/constants-python.xsl b/src/VBox/Main/glue/constants-python.xsl index df18f43b..3795d25e 100644 --- a/src/VBox/Main/glue/constants-python.xsl +++ b/src/VBox/Main/glue/constants-python.xsl @@ -8,7 +8,7 @@ XSLT stylesheet that generates VirtualBox_constants.py from VirtualBox.xidl. - Copyright (C) 2009 Oracle Corporation + Copyright (C) 2009-2013 Oracle Corporation This file is part of VirtualBox Open Source Edition (OSE), as available from http://www.virtualbox.org. This file is free software; @@ -26,79 +26,138 @@ indent="no"/> <xsl:template match="/"> -<xsl:text># Copyright (C) Oracle Corporation -# -# This file is part of VirtualBox Open Source Edition (OSE), as -# available from http://www.virtualbox.org. This file is free software; -# you can redistribute it and/or modify it under the terms of the GNU -# General Public License (GPL) as published by the Free Software -# Foundation, in version 2 as it comes in the "COPYING" file of the -# VirtualBox OSE distribution. VirtualBox OSE is distributed in the -# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. -# -# This file is autogenerated from VirtualBox.xidl, DO NOT EDIT! -# -</xsl:text> +<xsl:text># -*- coding: utf-8 -*- + +""" +VirtualBox COM/XPCOM constants. + +This file is autogenerated from VirtualBox.xidl, DO NOT EDIT! +""" + +__copyright__ = \ +""" +Copyright (C) 2009-2013 Oracle Corporation + +This file is part of VirtualBox Open Source Edition (OSE), as +available from http://www.virtualbox.org. This file is free software; +you can redistribute it and/or modify it under the terms of the GNU +General Public License (GPL) as published by the Free Software +Foundation, in version 2 as it comes in the "COPYING" file of the +VirtualBox OSE distribution. VirtualBox OSE is distributed in the +hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +""" + +__version__ = "$Revision: 87223 $"; + + + class VirtualBoxReflectionInfo: - def __init__(self, isSym): - self.isSym = isSym - - _Values = {<xsl:for-each select="//enum"> - '<xsl:value-of select="@name"/>':{ - <xsl:for-each select="const">'<xsl:value-of select="@name"/>':<xsl:value-of select="@value"/><xsl:if test="not(position()=last())">,</xsl:if> - </xsl:for-each>}<xsl:if test="not(position()=last())">,</xsl:if> - - </xsl:for-each>} - - _ValuesSym = {<xsl:for-each select="//enum"> - '<xsl:value-of select="@name"/>':{ - <xsl:for-each select="const">'<xsl:value-of select="@name"/>': '<xsl:value-of select="@name"/>'<xsl:if test="not(position()=last())">,</xsl:if> - </xsl:for-each>}<xsl:if test="not(position()=last())">,</xsl:if> - - </xsl:for-each>} - - _ValuesFlat = {<xsl:for-each select="//enum"> - <xsl:variable name="ename"> - <xsl:value-of select="@name"/> - </xsl:variable> - <xsl:for-each select="const"> - '<xsl:value-of select="$ename"/>_<xsl:value-of select="@name"/>':<xsl:value-of select="@value"/><xsl:if test="not(position()=last())">,</xsl:if> - </xsl:for-each> - <xsl:if test="not(position()=last())">,</xsl:if> - </xsl:for-each>} - - _ValuesFlatSym = {<xsl:for-each select="//enum"> - <xsl:variable name="ename"> - <xsl:value-of select="@name"/> - </xsl:variable> - <xsl:for-each select="const"> - <xsl:variable name="eval"> - <xsl:value-of select="concat($ename, '_', @name)"/> - </xsl:variable> - '<xsl:value-of select="$eval"/>': '<xsl:value-of select="@name"/>'<xsl:if test="not(position()=last())">,</xsl:if> - </xsl:for-each> - <xsl:if test="not(position()=last())">,</xsl:if> - </xsl:for-each>} - - def __getattr__(self,attr): - if self.isSym: - v = self._ValuesFlatSym.get(attr) - else: - v = self._ValuesFlat.get(attr) - if v is not None: - return v - else: - raise AttributeError - - def all_values(self,enum_name): - if self.isSym: - vals = self._ValuesSym.get(enum_name) - else: - vals = self._Values.get(enum_name) - if vals is not None: - return vals - else: - return {} + """ + Enum constants for the various python styles. + """ + + def __init__(self, fIsSym): + self.__fIsSym = fIsSym + __dValues = {</xsl:text> + + <xsl:for-each select="//enum"> + <xsl:text> + '</xsl:text> <xsl:value-of select="@name"/><xsl:text>': {</xsl:text> + <xsl:for-each select="const"> + <xsl:text> + '</xsl:text> + <xsl:value-of select="@name"/><xsl:text>': </xsl:text> + <xsl:value-of select="@value"/><xsl:text>,</xsl:text> + </xsl:for-each> + <xsl:text> + },</xsl:text> + </xsl:for-each> + <xsl:text> + } + + __dValuesSym = {</xsl:text> + <xsl:for-each select="//enum"> + <xsl:text> + '</xsl:text> <xsl:value-of select="@name"/> <xsl:text>': { </xsl:text> + <xsl:for-each select="const"> + <xsl:text> + '</xsl:text> <xsl:value-of select="@name"/> <xsl:text>': '</xsl:text> + <xsl:value-of select="@name"/> + <xsl:text>',</xsl:text> + </xsl:for-each> + <xsl:text> + },</xsl:text> + </xsl:for-each> +<xsl:text> + } + + __dValuesFlat = {</xsl:text> + <xsl:for-each select="//enum"> + <xsl:variable name="ename"> + <xsl:value-of select="@name"/> + </xsl:variable> + <xsl:for-each select="const"> + <xsl:text> + '</xsl:text> <xsl:value-of select="$ename"/> <xsl:text>_</xsl:text> + <xsl:value-of select="@name"/> <xsl:text>': </xsl:text> + <xsl:value-of select="@value"/><xsl:text>,</xsl:text> + </xsl:for-each> + </xsl:for-each> + <xsl:text> + # Result constants:</xsl:text> + <xsl:for-each select="//result[@value]"> + <xsl:text> + '</xsl:text> <xsl:value-of select="@name"/> <xsl:text>': </xsl:text> + <xsl:value-of select="@value"/><xsl:text>,</xsl:text> + </xsl:for-each> +<xsl:text> + } + + __dValuesFlatSym = {</xsl:text> + <xsl:for-each select="//enum"> + <xsl:variable name="ename"> + <xsl:value-of select="@name"/> + </xsl:variable> + <xsl:for-each select="const"> + <xsl:variable name="eval"> + <xsl:value-of select="concat($ename, '_', @name)"/> + </xsl:variable> + <xsl:text> + '</xsl:text> <xsl:value-of select="$eval"/> <xsl:text>': </xsl:text> + <xsl:text>'</xsl:text> <xsl:value-of select="@name"/> <xsl:text>',</xsl:text> + </xsl:for-each> + </xsl:for-each> + <xsl:text> + # Result constants:</xsl:text> + <xsl:for-each select="//result[@value]"> + <xsl:text> + '</xsl:text> <xsl:value-of select="@name"/> <xsl:text>': </xsl:text> + <xsl:text>'</xsl:text><xsl:value-of select="@name"/><xsl:text>',</xsl:text> + </xsl:for-each> + <xsl:text> + } + + def __getattr__(self, sAttrName): + if self.__fIsSym: + oValue = self.__dValuesFlatSym.get(sAttrName) + else: + oValue = self.__dValuesFlat.get(sAttrName) + if oValue is None: + raise AttributeError + return oValue + + def all_values(self, sEnumName): + """ Returns a dictionary with all the value names for a given enum type. """ + if self.__fIsSym: + dValues = self.__dValuesSym.get(sEnumName) + else: + dValues = self.__dValues.get(sEnumName) + if dValues is None: + dValues = {} + return dValues + +</xsl:text> </xsl:template> </xsl:stylesheet> + diff --git a/src/VBox/Main/glue/errorprint.cpp b/src/VBox/Main/glue/errorprint.cpp index 45979d62..b1b53ee8 100644 --- a/src/VBox/Main/glue/errorprint.cpp +++ b/src/VBox/Main/glue/errorprint.cpp @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Main/glue/glue-java.xsl b/src/VBox/Main/glue/glue-java.xsl index 0bcc4398..a1f47fc8 100644 --- a/src/VBox/Main/glue/glue-java.xsl +++ b/src/VBox/Main/glue/glue-java.xsl @@ -1,8 +1,8 @@ <xsl:stylesheet version = '1.0' - xmlns:xsl='http://www.w3.org/1999/XSL/Transform' - xmlns:vbox="http://www.virtualbox.org/" - xmlns:exsl="http://exslt.org/common" - extension-element-prefixes="exsl"> + xmlns:xsl='http://www.w3.org/1999/XSL/Transform' + xmlns:vbox="http://www.virtualbox.org/" + xmlns:exsl="http://exslt.org/common" + extension-element-prefixes="exsl"> <!-- @@ -10,7 +10,7 @@ XSLT stylesheet that generates Java glue code for XPCOM, MSCOM and JAX-WS from VirtualBox.xidl. - Copyright (C) 2010-2011 Oracle Corporation + Copyright (C) 2010-2014 Oracle Corporation This file is part of VirtualBox Open Source Edition (OSE), as available from http://www.virtualbox.org. This file is free software; @@ -32,35 +32,34 @@ - - - - - - - - - - - - - - - - - - - - - - --> <xsl:variable name="G_xsltFilename" select="'glue-java.xsl'" /> -<xsl:variable name="G_virtualBoxPackage" select="concat('org.virtualbox',$G_vboxApiSuffix)" /> -<xsl:variable name="G_virtualBoxPackageCom" select="concat('org.virtualbox',$G_vboxApiSuffix,'.',$G_vboxGlueStyle)" /> -<xsl:variable name="G_virtualBoxWsdl" select="concat(concat('"vboxwebService',$G_vboxApiSuffix), '.wsdl"')" /> -<!-- collect all interfaces with "wsmap='suppress'" in a global variable for - quick lookup --> +<xsl:variable name="G_virtualBoxPackage" select="concat('org.virtualbox', $G_vboxApiSuffix)" /> +<xsl:variable name="G_virtualBoxPackageCom" select="concat('org.virtualbox', $G_vboxApiSuffix, '.', $G_vboxGlueStyle)" /> +<xsl:variable name="G_virtualBoxWsdl" select="concat('"vboxwebService', $G_vboxApiSuffix, '.wsdl"')" /> +<!-- collect all interfaces with "wsmap='suppress'" in a global variable for quick lookup --> <xsl:variable name="G_setSuppressedInterfaces" select="//interface[@wsmap='suppress']" /> -<xsl:include href="../webservice/websrv-shared.inc.xsl" /> +<xsl:include href="../idl/typemap-shared.inc.xsl" /> <xsl:strip-space elements="*"/> <xsl:template name="fileheader"> <xsl:param name="name" /> <xsl:text>/* - * Copyright (C) 2010-2011 Oracle Corporation + * Copyright (C) 2010-2014 Oracle Corporation * - * This file is part of the VirtualBox SDK, as available from - * http://www.virtualbox.org. This library is free software; you can - * redistribute it and/or modify it under the terms of the GNU Lesser General - * Public License as published by the Free Software Foundation, in version 2.1 - * as it comes in the "COPYING.LIB" file of the VirtualBox SDK distribution. - * 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 Lesser General Public - * License for more details. + * This file is part of the VirtualBox SDK, as available from + * http://www.virtualbox.org. This library is free software; you can + * redistribute it and/or modify it under the terms of the GNU Lesser General + * Public License as published by the Free Software Foundation, in version 2.1 + * as it comes in the "COPYING.LIB" file of the VirtualBox SDK distribution. + * 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 Lesser General Public + * License for more details. * </xsl:text> - <xsl:value-of select="concat(' * ',$name)"/> + <xsl:value-of select="concat(' * ', $name)"/> <xsl:text> * * DO NOT EDIT! This is a generated file. @@ -75,39 +74,48 @@ <xsl:param name="file" /> <xsl:param name="package" /> - <xsl:value-of select="concat(' // ##### BEGINFILE "', $G_vboxDirPrefix, $file, '" ')" /> - <xsl:call-template name="fileheader"> - <xsl:with-param name="name" select="$file" /> - </xsl:call-template> + <xsl:choose> + <xsl:when test="$filelistonly=''"> + <xsl:value-of select="concat(' // ##### BEGINFILE "', $G_vboxDirPrefix, $file, '" ')" /> + <xsl:call-template name="fileheader"> + <xsl:with-param name="name" select="$file" /> + </xsl:call-template> - <xsl:value-of select="concat('package ',$package,'; ')" /> - <xsl:value-of select="concat('import ',$G_virtualBoxPackageCom,'.*; ')" /> + <xsl:value-of select="concat('package ', $package, '; ')" /> + <xsl:value-of select="concat('import ', $G_virtualBoxPackageCom, '.*; ')" /> - <xsl:choose> - <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="'import org.mozilla.interfaces.*; '" /> - </xsl:when> + <xsl:choose> + <xsl:when test="$G_vboxGlueStyle='xpcom'"> + <xsl:text>import org.mozilla.interfaces.*; </xsl:text> + </xsl:when> - <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="'import com.jacob.com.*; '" /> - <xsl:value-of select="'import com.jacob.activeX.ActiveXComponent; '" /> - </xsl:when> + <xsl:when test="$G_vboxGlueStyle='mscom'"> + <xsl:text>import com.jacob.com.*; </xsl:text> + <xsl:text>import com.jacob.activeX.ActiveXComponent; </xsl:text> + </xsl:when> - <xsl:when test="$G_vboxGlueStyle='jaxws'"> - <xsl:value-of select="'import javax.xml.ws.*; '" /> - </xsl:when> + <xsl:when test="$G_vboxGlueStyle='jaxws'"> + <xsl:text>import javax.xml.ws.*; </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="'no header rule (startFile)'" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:when> <xsl:otherwise> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="'no header rule (startFile)'" /> - </xsl:call-template> + <xsl:value-of select="concat('	', $G_vboxDirPrefix, $file, ' \ ')"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="endFile"> - <xsl:param name="file" /> - <xsl:value-of select="concat(' // ##### ENDFILE "', $file, '" ')" /> + <xsl:param name="file" /> + <xsl:if test="$filelistonly=''"> + <xsl:value-of select="concat(' // ##### ENDFILE "', $file, '" ')" /> + </xsl:if> </xsl:template> @@ -115,15 +123,23 @@ <xsl:param name="haystack"/> <xsl:param name="needle"/> <xsl:param name="replacement"/> + <xsl:param name="onlyfirst" select="false"/> <xsl:choose> - <xsl:when test="contains($haystack,$needle)"> - <xsl:value-of select="substring-before($haystack,$needle)"/> + <xsl:when test="contains($haystack, $needle)"> + <xsl:value-of select="substring-before($haystack, $needle)"/> <xsl:value-of select="$replacement"/> - <xsl:call-template name="string-replace"> - <xsl:with-param name="haystack" select="substring-after($haystack,$needle)"/> - <xsl:with-param name="needle" select="$needle"/> - <xsl:with-param name="replacement" select="$replacement"/> - </xsl:call-template> + <xsl:choose> + <xsl:when test="$onlyfirst = 'true'"> + <xsl:value-of select="substring-after($haystack, $needle)"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="string-replace"> + <xsl:with-param name="haystack" select="substring-after($haystack, $needle)"/> + <xsl:with-param name="needle" select="$needle"/> + <xsl:with-param name="replacement" select="$replacement"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$haystack"/> @@ -131,6 +147,48 @@ </xsl:choose> </xsl:template> +<xsl:template name="string-trim"> + <xsl:param name="text"/> + + <xsl:variable name="begin" select="substring($text, 1, 1)"/> + <xsl:choose> + <xsl:when test="$begin = ' ' or $begin = ' ' or $begin = ' '"> + <xsl:call-template name="string-trim"> + <xsl:with-param name="text" select="substring($text, 2)"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="end" select="substring($text, string-length($text) - 1, 1)"/> + <xsl:choose> + <xsl:when test="$end = ' ' or $end = ' ' or $end = ' '"> + <xsl:call-template name="string-trim"> + <xsl:with-param name="text" select="substring($text, 1, string-length($text) - 1)"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:choose> + <xsl:when test="contains($text, ' ')"> + <xsl:variable name="tmptext"> + <xsl:call-template name="string-replace"> + <xsl:with-param name="haystack" select="$text"/> + <xsl:with-param name="needle" select="' '"/> + <xsl:with-param name="replacement" select="' '"/> + </xsl:call-template> + </xsl:variable> + <xsl:call-template name="string-trim"> + <xsl:with-param name="text" select="$tmptext"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$text"/> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + <!-- descriptions --> <xsl:template match="*/text()"> @@ -160,18 +218,24 @@ </xsl:call-template> </xsl:variable> - <xsl:value-of select="$rep3"/> + <xsl:variable name="rep4"> + <xsl:call-template name="string-trim"> + <xsl:with-param name="text" select="$rep3"/> + </xsl:call-template> + </xsl:variable> + + <xsl:value-of select="$rep4"/> </xsl:template> <!-- - * all sub-elements that are not explicitly matched are considered to be - * html tags and copied w/o modifications + * all sub-elements that are not explicitly matched are considered to be + * html tags and copied w/o modifications --> <xsl:template match="desc//*"> <xsl:variable name="tagname" select="local-name()"/> - <xsl:value-of select="concat('<',$tagname,'>')"/> + <xsl:value-of select="concat('<', $tagname, '>')"/> <xsl:apply-templates/> - <xsl:value-of select="concat('</',$tagname,'>')"/> + <xsl:value-of select="concat('</', $tagname, '>')"/> </xsl:template> <xsl:template name="emit_refsig"> @@ -214,14 +278,14 @@ </xsl:when> <xsl:otherwise> <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="concat('unknown reference destination in @see/@link: context=',$context,' identifier=',$identifier)" /> + <xsl:with-param name="msg" select="concat('unknown reference destination in @see/@link: context=', $context, ' identifier=', $identifier)" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- - * link + * link --> <xsl:template match="desc//link"> <xsl:text>{@link </xsl:text> @@ -231,10 +295,15 @@ <xsl:template match="link" mode="middle"> <xsl:variable name="linktext"> - <xsl:value-of select="translate(@to,'_','#')"/> + <xsl:call-template name="string-replace"> + <xsl:with-param name="haystack" select="@to"/> + <xsl:with-param name="needle" select="'_'"/> + <xsl:with-param name="replacement" select="'#'"/> + <xsl:with-param name="onlyfirst" select="'true'"/> + </xsl:call-template> </xsl:variable> <xsl:choose> - <xsl:when test="substring($linktext,1,1)='#'"> + <xsl:when test="substring($linktext, 1, 1)='#'"> <xsl:variable name="context"> <xsl:choose> <xsl:when test="local-name(../..)='interface' or local-name(../..)='enum'"> @@ -254,13 +323,13 @@ </xsl:when> <xsl:otherwise> <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="concat('cannot determine context for identifier ',$linktext)" /> + <xsl:with-param name="msg" select="concat('cannot determine context for identifier ', $linktext)" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="linkname"> - <xsl:value-of select="substring($linktext,2)"/> + <xsl:value-of select="substring($linktext, 2)"/> </xsl:variable> <xsl:text>#</xsl:text> <xsl:call-template name="emit_refsig"> @@ -268,26 +337,26 @@ <xsl:with-param name="identifier" select="$linkname"/> </xsl:call-template> </xsl:when> - <xsl:when test="contains($linktext,'::')"> + <xsl:when test="contains($linktext, '::')"> <xsl:variable name="context"> - <xsl:value-of select="substring-before($linktext,'::')"/> + <xsl:value-of select="substring-before($linktext, '::')"/> </xsl:variable> <xsl:variable name="linkname"> - <xsl:value-of select="substring-after($linktext,'::')"/> + <xsl:value-of select="substring-after($linktext, '::')"/> </xsl:variable> - <xsl:value-of select="concat($G_virtualBoxPackage,'.',$context,'#')"/> + <xsl:value-of select="concat($G_virtualBoxPackage, '.', $context, '#')"/> <xsl:call-template name="emit_refsig"> <xsl:with-param name="context" select="$context"/> <xsl:with-param name="identifier" select="$linkname"/> </xsl:call-template> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat($G_virtualBoxPackage,'.',$linktext)"/> + <xsl:value-of select="concat($G_virtualBoxPackage, '.', $linktext)"/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- - * note + * note --> <xsl:template match="desc/note"> <xsl:if test="not(@internal='yes')"> @@ -298,12 +367,12 @@ </xsl:template> <!-- - * see + * see --> <xsl:template match="desc/see"> <!-- TODO: quirk in our xidl file: only one <see> tag with <link> nested into it, translate this to multiple @see lines and strip the rest. - Should be replaced in the xidl by multiple <see> without nested tag --> + Should be replaced in the xidl by multiple <see> without nested tag --> <xsl:text> </xsl:text> <xsl:apply-templates match="link"/> </xsl:template> @@ -317,18 +386,18 @@ </xsl:template> <!-- - * common comment prologue (handles group IDs) + * common comment prologue (handles group IDs) --> <xsl:template match="desc" mode="begin"> <xsl:param name="id" select="@group | preceding::descGroup[1]/@id"/> - <xsl:text>/** </xsl:text> + <xsl:text> /** </xsl:text> <xsl:if test="$id"> - <xsl:value-of select="concat(' @ingroup ',$id,' ')"/> + <xsl:value-of select="concat(' @ingroup ', $id, ' ')"/> </xsl:if> </xsl:template> <!-- - * common middle part of the comment block + * common middle part of the comment block --> <xsl:template match="desc" mode="middle"> <xsl:apply-templates select="text() | *[not(self::note or self::see)]"/> @@ -337,7 +406,7 @@ </xsl:template> <!-- - * result part of the comment block + * result part of the comment block --> <xsl:template match="desc" mode="results"> <xsl:if test="result"> @@ -347,10 +416,10 @@ <xsl:text><tr></xsl:text> <xsl:choose> <xsl:when test="ancestor::library/result[@name=current()/@name]"> - <xsl:value-of select="concat('<td>@link ::',@name,' ',@name,'</td>')"/> + <xsl:value-of select="concat('<td>@link ::', @name, ' ', @name, '</td>')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('<td>',@name,'</td>')"/> + <xsl:value-of select="concat('<td>', @name, '</td>')"/> </xsl:otherwise> </xsl:choose> <xsl:text><td></xsl:text> @@ -363,17 +432,15 @@ </xsl:template> <!-- - * translates the string to uppercase + * translates the string to uppercase --> <xsl:template name="uppercase"> <xsl:param name="str" select="."/> - <xsl:value-of select=" - translate($str,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ') - "/> + <xsl:value-of select="translate($str, $G_lowerCase, $G_upperCase)"/> </xsl:template> <!-- - * comment for interfaces + * comment for interfaces --> <xsl:template match="desc" mode="interface"> <xsl:apply-templates select="." mode="begin"/> @@ -386,7 +453,7 @@ </xsl:template> <!-- - * comment for attribute getters + * comment for attribute getters --> <xsl:template match="desc" mode="attribute_get"> <xsl:apply-templates select="." mode="begin"/> @@ -400,11 +467,11 @@ </xsl:call-template> <xsl:text> </xsl:text> <xsl:apply-templates select="see"/> - <xsl:text> */ </xsl:text> + <xsl:text>*/ </xsl:text> </xsl:template> <!-- - * comment for attribute setters + * comment for attribute setters --> <xsl:template match="desc" mode="attribute_set"> <xsl:apply-templates select="." mode="begin"/> @@ -422,7 +489,7 @@ </xsl:template> <!-- - * comment for methods + * comment for methods --> <xsl:template match="desc" mode="method"> <xsl:apply-templates select="." mode="begin"/> @@ -438,7 +505,7 @@ </xsl:template> <!-- - * comment for method parameters + * comment for method parameters --> <xsl:template match="method/param/desc"> <xsl:if test="text() | *[not(self::note or self::see)]"> @@ -458,7 +525,7 @@ </xsl:template> <!-- - * comment for enums + * comment for enums --> <xsl:template match="desc" mode="enum"> <xsl:apply-templates select="." mode="begin"/> @@ -471,7 +538,7 @@ </xsl:template> <!-- - * comment for enum values + * comment for enum values --> <xsl:template match="desc" mode="enum_const"> <xsl:apply-templates select="." mode="begin"/> @@ -480,7 +547,7 @@ </xsl:template> <!-- - * ignore descGroups by default (processed in /idl) + * ignore descGroups by default (processed in /idl) --> <xsl:template match="descGroup"/> @@ -497,47 +564,55 @@ <xsl:with-param name="package" select="$G_virtualBoxPackage" /> </xsl:call-template> - <xsl:apply-templates select="desc" mode="enum"/> - <xsl:value-of select="concat('public enum ', $enumname, ' { ')" /> - <xsl:for-each select="const"> - <xsl:apply-templates select="desc" mode="enum_const"/> - <xsl:variable name="enumconst" select="@name" /> - <xsl:value-of select="concat(' ', $enumconst, '(', @value, ')')" /> - <xsl:choose> - <xsl:when test="not(position()=last())"> - <xsl:text>, </xsl:text> - </xsl:when> - <xsl:otherwise> - <xsl:text>; </xsl:text> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - - <xsl:text> </xsl:text> - <xsl:text> private final int value; </xsl:text> - - <xsl:value-of select="concat(' ', $enumname, '(int v) { ')" /> - <xsl:text> value = v; </xsl:text> - <xsl:text> } </xsl:text> - - <xsl:text> public int value() { </xsl:text> - <xsl:text> return value; </xsl:text> - <xsl:text> } </xsl:text> - - <xsl:value-of select="concat(' public static ', $enumname, ' fromValue(long v) { ')" /> - <xsl:value-of select="concat(' for (', $enumname, ' c: ', $enumname, '.values()) { ')" /> - <xsl:text> if (c.value == (int)v) { </xsl:text> - <xsl:text> return c; </xsl:text> - <xsl:text> } </xsl:text> - <xsl:text> } </xsl:text> - <xsl:text> throw new IllegalArgumentException(Long.toString(v)); </xsl:text> - <xsl:text> } </xsl:text> - - <xsl:value-of select="concat(' public static ', $enumname, ' fromValue(String v) { ')" /> - <xsl:value-of select="concat(' return valueOf(',$enumname, '.class, v); ')" /> - <xsl:value-of select=" ' } '" /> + <xsl:if test="$filelistonly=''"> + <xsl:apply-templates select="desc" mode="enum"/> + <xsl:value-of select="concat('public enum ', $enumname, ' ')" /> + <xsl:text>{ </xsl:text> + <xsl:for-each select="const"> + <xsl:apply-templates select="desc" mode="enum_const"/> + <xsl:variable name="enumconst" select="@name" /> + <xsl:value-of select="concat(' ', $enumconst, '(', @value, ')')" /> + <xsl:choose> + <xsl:when test="not(position()=last())"> + <xsl:text>, </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>; </xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:for-each> - <xsl:text>} </xsl:text> + <xsl:text> </xsl:text> + <xsl:text> private final int value; </xsl:text> + + <xsl:value-of select="concat(' ', $enumname, '(int v) ')" /> + <xsl:text> { </xsl:text> + <xsl:text> value = v; </xsl:text> + <xsl:text> } </xsl:text> + + <xsl:text> public int value() </xsl:text> + <xsl:text> { </xsl:text> + <xsl:text> return value; </xsl:text> + <xsl:text> } </xsl:text> + + <xsl:value-of select="concat(' public static ', $enumname, ' fromValue(long v) ')" /> + <xsl:text> { </xsl:text> + <xsl:value-of select="concat(' for (', $enumname, ' c: ', $enumname, '.values()) ')" /> + <xsl:text> { </xsl:text> + <xsl:text> if (c.value == (int)v) </xsl:text> + <xsl:text> { </xsl:text> + <xsl:text> return c; </xsl:text> + <xsl:text> } </xsl:text> + <xsl:text> } </xsl:text> + <xsl:text> throw new IllegalArgumentException(Long.toString(v)); </xsl:text> + <xsl:text> } </xsl:text> + + <xsl:value-of select="concat(' public static ', $enumname, ' fromValue(String v) ')" /> + <xsl:text> { </xsl:text> + <xsl:value-of select="concat(' return valueOf(', $enumname, '.class, v); ')" /> + <xsl:text> } </xsl:text> + <xsl:text>} </xsl:text> + </xsl:if> <xsl:call-template name="endFile"> <xsl:with-param name="file" select="$filename" /> @@ -546,32 +621,39 @@ </xsl:template> <xsl:template name="startExcWrapper"> - - <xsl:value-of select="' try { '" /> - + <xsl:text> try </xsl:text> + <xsl:text> { </xsl:text> </xsl:template> <xsl:template name="endExcWrapper"> <xsl:choose> <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="' } catch (org.mozilla.xpcom.XPCOMException e) { '" /> - <xsl:value-of select="' throw new VBoxException(e, e.getMessage()); '" /> - <xsl:value-of select="' } '" /> + <xsl:text> } </xsl:text> + <xsl:text> catch (org.mozilla.xpcom.XPCOMException e) </xsl:text> + <xsl:text> { </xsl:text> + <xsl:text> throw new VBoxException(e.getMessage(), e); </xsl:text> + <xsl:text> } </xsl:text> </xsl:when> <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="' } catch (com.jacob.com.ComException e) { '" /> - <xsl:value-of select="' throw new VBoxException(e, e.getMessage()); '" /> - <xsl:value-of select="' } '" /> + <xsl:text> } </xsl:text> + <xsl:text> catch (com.jacob.com.ComException e) </xsl:text> + <xsl:text> { </xsl:text> + <xsl:text> throw new VBoxException(e.getMessage(), e); </xsl:text> + <xsl:text> } </xsl:text> </xsl:when> <xsl:when test="$G_vboxGlueStyle='jaxws'"> - <xsl:value-of select="' } catch (InvalidObjectFaultMsg e) { '" /> - <xsl:value-of select="' throw new VBoxException(e, e.getMessage()); '" /> - <xsl:value-of select="' } catch (RuntimeFaultMsg e) { '" /> - <xsl:value-of select="' throw new VBoxException(e, e.getMessage()); '" /> - <xsl:value-of select="' } '" /> + <xsl:text> } </xsl:text> + <xsl:text> catch (InvalidObjectFaultMsg e) </xsl:text> + <xsl:text> { </xsl:text> + <xsl:text> throw new VBoxException(e.getMessage(), e, this.port); </xsl:text> + <xsl:text> } </xsl:text> + <xsl:text> catch (RuntimeFaultMsg e) </xsl:text> + <xsl:text> { </xsl:text> + <xsl:text> throw new VBoxException(e.getMessage(), e, this.port); </xsl:text> + <xsl:text> } </xsl:text> </xsl:when> <xsl:otherwise> @@ -587,15 +669,15 @@ <xsl:choose> <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="concat('org.mozilla.interfaces.',$ifname)" /> + <xsl:value-of select="concat('org.mozilla.interfaces.', $ifname)" /> </xsl:when> <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="'com.jacob.com.Dispatch'" /> + <xsl:text>com.jacob.com.Dispatch</xsl:text> </xsl:when> <xsl:when test="$G_vboxGlueStyle='jaxws'"> - <xsl:value-of select="'String'" /> + <xsl:text>String</xsl:text> </xsl:when> <xsl:otherwise> @@ -611,19 +693,20 @@ <xsl:param name="name" /> <xsl:param name="origname" /> <xsl:param name="collPrefix" /> - <xsl:choose> - <xsl:when test="//enum[@name=$name] or //enum[@name=$origname]"> - <xsl:value-of select="concat($G_virtualBoxPackage, concat('.', $name))" /> - </xsl:when> - <xsl:when test="//interface[@name=$name]"> - <xsl:value-of select="concat($G_virtualBoxPackage, concat('.', $name))" /> - </xsl:when> - <xsl:otherwise> + + <xsl:choose> + <xsl:when test="//enum[@name=$name] or //enum[@name=$origname]"> + <xsl:value-of select="concat($G_virtualBoxPackage, concat('.', $name))" /> + </xsl:when> + <xsl:when test="//interface[@name=$name]"> + <xsl:value-of select="concat($G_virtualBoxPackage, concat('.', $name))" /> + </xsl:when> + <xsl:otherwise> <xsl:call-template name="fatalError"> <xsl:with-param name="msg" select="concat('fullClassName: Type "', $name, '" is not supported.')" /> </xsl:call-template> - </xsl:otherwise> - </xsl:choose> + </xsl:otherwise> + </xsl:choose> </xsl:template> <xsl:template name="typeIdl2Glue"> @@ -636,14 +719,14 @@ <xsl:variable name="needlist" select="($needarray) and not($type='octet')" /> <xsl:if test="($needlist)"> - <xsl:value-of select="'List'" /> + <xsl:text>List</xsl:text> <xsl:if test="not($skiplisttype='yes')"> - <xsl:value-of select="'<'" /> + <xsl:text><</xsl:text> </xsl:if> </xsl:if> <xsl:if test="not($needlist) or not($skiplisttype='yes')"> - <!-- look up Java type from IDL type from table array in websrv-shared.inc.xsl --> + <!-- look up Java type from IDL type from table array in typemap-shared.inc.xsl --> <xsl:variable name="javatypefield" select="exsl:node-set($G_aSharedTypes)/type[@idlname=$type]/@javaname" /> <xsl:choose> @@ -664,11 +747,11 @@ <xsl:choose> <xsl:when test="($needlist)"> <xsl:if test="not($skiplisttype='yes')"> - <xsl:value-of select="'>'" /> + <xsl:text>></xsl:text> </xsl:if> </xsl:when> <xsl:when test="($needarray)"> - <xsl:value-of select="'[]'" /> + <xsl:text>[]</xsl:text> </xsl:when> </xsl:choose> </xsl:template> @@ -687,43 +770,43 @@ <xsl:choose> <xsl:when test="$type='long long'"> - <xsl:value-of select="'long'" /> + <xsl:text>long</xsl:text> </xsl:when> <xsl:when test="$type='unsigned long'"> - <xsl:value-of select="'long'" /> + <xsl:text>long</xsl:text> </xsl:when> <xsl:when test="$type='long'"> - <xsl:value-of select="'int'" /> + <xsl:text>int</xsl:text> </xsl:when> <xsl:when test="$type='unsigned short'"> - <xsl:value-of select="'int'" /> + <xsl:text>int</xsl:text> </xsl:when> <xsl:when test="$type='short'"> - <xsl:value-of select="'short'" /> + <xsl:text>short</xsl:text> </xsl:when> <xsl:when test="$type='octet'"> - <xsl:value-of select="'byte'" /> + <xsl:text>byte</xsl:text> </xsl:when> <xsl:when test="$type='boolean'"> - <xsl:value-of select="'boolean'" /> + <xsl:text>boolean</xsl:text> </xsl:when> <xsl:when test="$type='$unknown'"> - <xsl:value-of select="'nsISupports'"/> + <xsl:text>nsISupports</xsl:text> </xsl:when> <xsl:when test="$type='wstring'"> - <xsl:value-of select="'String'" /> + <xsl:text>String</xsl:text> </xsl:when> <xsl:when test="$type='uuid'"> - <xsl:value-of select="'String'" /> + <xsl:text>String</xsl:text> </xsl:when> <xsl:when test="//interface[@name=$type]/@wsmap='struct'"> @@ -739,7 +822,7 @@ </xsl:when> <xsl:when test="//enum[@name=$type]"> - <xsl:value-of select="'long'" /> + <xsl:text>long</xsl:text> </xsl:when> <xsl:otherwise> @@ -750,27 +833,27 @@ </xsl:choose> <xsl:if test="$needarray"> - <xsl:value-of select="'[]'" /> + <xsl:text>[]</xsl:text> </xsl:if> </xsl:when> <xsl:when test="($G_vboxGlueStyle='mscom')"> - <xsl:value-of select="'Variant'"/> + <xsl:text>Variant</xsl:text> </xsl:when> <xsl:when test="($G_vboxGlueStyle='jaxws')"> <xsl:variable name="needarray" select="($safearray='yes' and not($type='octet')) and not($forceelem='yes')" /> <xsl:if test="$needarray"> - <xsl:value-of select="'List<'" /> + <xsl:text>List<</xsl:text> </xsl:if> <xsl:choose> <xsl:when test="$type='$unknown'"> - <xsl:value-of select="'String'" /> + <xsl:text>String</xsl:text> </xsl:when> <xsl:when test="//interface[@name=$type]/@wsmap='managed'"> - <xsl:value-of select="'String'" /> + <xsl:text>String</xsl:text> </xsl:when> <xsl:when test="//interface[@name=$type]/@wsmap='struct'"> @@ -783,51 +866,51 @@ <!-- we encode byte arrays as Base64 strings. --> <xsl:when test="$type='octet'"> - <xsl:value-of select="'/*base64*/String'" /> + <xsl:text>/*base64*/String</xsl:text> </xsl:when> <xsl:when test="$type='long long'"> - <xsl:value-of select="'Long'" /> + <xsl:text>Long</xsl:text> </xsl:when> <xsl:when test="$type='unsigned long'"> - <xsl:value-of select="'Long'" /> + <xsl:text>Long</xsl:text> </xsl:when> <xsl:when test="$type='long'"> - <xsl:value-of select="'Integer'" /> + <xsl:text>Integer</xsl:text> </xsl:when> <xsl:when test="$type='unsigned short'"> - <xsl:value-of select="'Integer'" /> + <xsl:text>Integer</xsl:text> </xsl:when> <xsl:when test="$type='short'"> - <xsl:value-of select="'Short'" /> + <xsl:text>Short</xsl:text> </xsl:when> <xsl:when test="$type='boolean'"> - <xsl:value-of select="'Boolean'" /> + <xsl:text>Boolean</xsl:text> </xsl:when> <xsl:when test="$type='wstring'"> - <xsl:value-of select="'String'" /> + <xsl:text>String</xsl:text> </xsl:when> <xsl:when test="$type='uuid'"> - <xsl:value-of select="'String'" /> + <xsl:text>String</xsl:text> </xsl:when> <xsl:otherwise> <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="concat('Unhandled type ', $type,' (typeIdl2Back)')" /> + <xsl:with-param name="msg" select="concat('Unhandled type ', $type, ' (typeIdl2Back)')" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> <xsl:if test="$needarray"> - <xsl:value-of select="'>'" /> + <xsl:text>></xsl:text> </xsl:if> </xsl:when> @@ -875,16 +958,16 @@ <xsl:with-param name="forceelem" select="'yes'" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat('Helper.wrap2(',$elemgluetype, '.class, ', $elembacktype, '.class, ', $value,')')"/> + <xsl:value-of select="concat('Helper.wrap2(', $elemgluetype, '.class, ', $elembacktype, '.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('(', $value, ' != null) ? new ', $gluetype, '(', $value,') : null')" /> + <xsl:value-of select="concat('(', $value, ' != null) ? new ', $gluetype, '(', $value, ') : null')" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="//enum[@name=$idltype]"> - <xsl:choose> + <xsl:choose> <xsl:when test="$safearray='yes'"> <xsl:variable name="elembacktype"> <xsl:call-template name="typeIdl2Back"> @@ -893,12 +976,12 @@ <xsl:with-param name="forceelem" select="'yes'" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat('Helper.wrapEnum(',$elemgluetype, '.class, ', $value,')')"/> + <xsl:value-of select="concat('Helper.wrapEnum(', $elemgluetype, '.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat($gluetype,'.fromValue(', $value,')')"/> + <xsl:value-of select="concat($gluetype, '.fromValue(', $value, ')')"/> </xsl:otherwise> - </xsl:choose> + </xsl:choose> </xsl:when> <xsl:otherwise> @@ -907,7 +990,7 @@ <xsl:value-of select="$value"/> </xsl:when> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.wrap(', $value,')')"/> + <xsl:value-of select="concat('Helper.wrap(', $value, ')')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$value"/> @@ -943,54 +1026,54 @@ <xsl:value-of select="concat('Helper.wrapBytes(', $value, '.toSafeArray())')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('Helper.wrap(', $elemgluetype, '.class, ', $value,'.toSafeArray())')"/> + <xsl:value-of select="concat('Helper.wrap(', $elemgluetype, '.class, ', $value, '.toSafeArray())')"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="//interface[@name=$idltype] or $idltype='$unknown'"> - <xsl:value-of select="concat('Helper.wrapDispatch(',$gluetype, '.class, ', $value,'.getDispatch())')"/> + <xsl:value-of select="concat('Helper.wrapDispatch(', $gluetype, '.class, ', $value, '.getDispatch())')"/> </xsl:when> <xsl:when test="//enum[@name=$idltype]"> - <xsl:value-of select="concat($gluetype,'.fromValue(', $value,'.getInt())')"/> + <xsl:value-of select="concat($gluetype, '.fromValue(', $value, '.getInt())')"/> </xsl:when> <xsl:when test="$idltype='wstring'"> - <xsl:value-of select="concat($value,'.getString()')"/> + <xsl:value-of select="concat($value, '.getString()')"/> </xsl:when> <xsl:when test="$idltype='uuid'"> - <xsl:value-of select="concat($value,'.getString()')"/> + <xsl:value-of select="concat($value, '.getString()')"/> </xsl:when> - <xsl:when test="$idltype='boolean'"> - <xsl:value-of select="concat($value,'.toBoolean()')"/> + <xsl:when test="$idltype='boolean'"> + <xsl:value-of select="concat($value, '.toBoolean()')"/> </xsl:when> <xsl:when test="$idltype='unsigned short'"> - <xsl:value-of select="concat('(int)', $value,'.getShort()')"/> + <xsl:value-of select="concat('(int)', $value, '.getShort()')"/> </xsl:when> - <xsl:when test="$idltype='short'"> - <xsl:value-of select="concat($value,'.getShort()')"/> + <xsl:when test="$idltype='short'"> + <xsl:value-of select="concat($value, '.getShort()')"/> </xsl:when> <xsl:when test="$idltype='long'"> - <xsl:value-of select="concat($value,'.getInt()')"/> + <xsl:value-of select="concat($value, '.getInt()')"/> </xsl:when> <xsl:when test="$idltype='unsigned long'"> - <xsl:value-of select="concat('(long)', $value,'.getInt()')"/> + <xsl:value-of select="concat('(long)', $value, '.getInt()')"/> </xsl:when> <xsl:when test="$idltype='long'"> - <xsl:value-of select="concat($value,'.getInt()')"/> + <xsl:value-of select="concat($value, '.getInt()')"/> </xsl:when> <xsl:when test="$idltype='long long'"> - <xsl:value-of select="concat($value,'.getLong()')"/> + <xsl:value-of select="concat($value, '.getLong()')"/> </xsl:when> <xsl:otherwise> @@ -1035,19 +1118,19 @@ </xsl:variable> <xsl:choose> <xsl:when test="$isstruct"> - <xsl:value-of select="concat('Helper.wrap2(',$elemgluetype, '.class, ', $elembacktype, '.class, port, ', $value,')')"/> + <xsl:value-of select="concat('Helper.wrap2(', $elemgluetype, '.class, ', $elembacktype, '.class, port, ', $value, ')')"/> </xsl:when> <xsl:when test="//enum[@name=$idltype]"> - <xsl:value-of select="concat('Helper.convertEnums(',$elembacktype, '.class, ', $elemgluetype, '.class, ', $value,')')"/> + <xsl:value-of select="concat('Helper.convertEnums(', $elembacktype, '.class, ', $elemgluetype, '.class, ', $value, ')')"/> </xsl:when> <xsl:when test="//interface[@name=$idltype] or $idltype='$unknown'"> - <xsl:value-of select="concat('Helper.wrap(',$elemgluetype,'.class, port, ', $value,')')"/> + <xsl:value-of select="concat('Helper.wrap(', $elemgluetype, '.class, port, ', $value, ')')"/> </xsl:when> <xsl:when test="$idltype='octet'"> - <xsl:value-of select="concat('Helper.decodeBase64(',$value,')')"/> + <xsl:value-of select="concat('Helper.decodeBase64(', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="$value" /> + <xsl:value-of select="$value" /> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1055,7 +1138,7 @@ <xsl:otherwise> <xsl:choose> <xsl:when test="//enum[@name=$idltype]"> - <xsl:value-of select="concat($gluetype,'.fromValue(', $value,'.value())')"/> + <xsl:value-of select="concat($gluetype, '.fromValue(', $value, '.value())')"/> </xsl:when> <xsl:when test="$idltype='boolean'"> <xsl:value-of select="$value"/> @@ -1085,15 +1168,15 @@ <xsl:value-of select="$value"/> </xsl:when> <xsl:when test="$isstruct"> - <xsl:value-of select="concat('(', $value, ' != null) ? new ', $gluetype, '(', $value,', port) : null')" /> + <xsl:value-of select="concat('(', $value, ' != null) ? new ', $gluetype, '(', $value, ', port) : null')" /> </xsl:when> <xsl:when test="//interface[@name=$idltype] or $idltype='$unknown'"> <!-- if the MOR string is empty, that means NULL, so return NULL instead of an object then --> - <xsl:value-of select="concat('(', $value, '.length() > 0) ? new ', $gluetype, '(', $value,', port) : null')" /> + <xsl:value-of select="concat('(', $value, '.length() > 0) ? new ', $gluetype, '(', $value, ', port) : null')" /> </xsl:when> <xsl:otherwise> <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="concat('Unhandled type ', $idltype, ' (cookOutParamJaxws)')" /> + <xsl:with-param name="msg" select="concat('Unhandled type ', $idltype, ' (cookOutParamJaxws)')" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> @@ -1177,21 +1260,21 @@ <xsl:with-param name="forceelem" select="'yes'" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat('Helper.unwrap2(',$elemgluetype, '.class, ', $elembacktype, '.class, ', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrap2(', $elemgluetype, '.class, ', $elembacktype, '.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('(', $value, ' != null) ? ', $value, '.getTypedWrapped() : null')" /> + <xsl:value-of select="concat('(', $value, ' != null) ? ', $value, '.getTypedWrapped() : null')" /> </xsl:otherwise> </xsl:choose> </xsl:when> - <xsl:when test="$idltype='$unknown'"> - <xsl:choose> + <xsl:when test="$idltype='$unknown'"> + <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrap2(',$elemgluetype, '.class, nsISupports.class, ', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrap2(', $elemgluetype, '.class, nsISupports.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('(', $value, ' != null) ? (nsISupports)', $value, '.getWrapped() : null')" /> + <xsl:value-of select="concat('(', $value, ' != null) ? (nsISupports)', $value, '.getWrapped() : null')" /> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1199,10 +1282,10 @@ <xsl:when test="//enum[@name=$idltype]"> <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrapEnum(', $elemgluetype, '.class,', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrapEnum(', $elemgluetype, '.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat($value,'.value()')"/> + <xsl:value-of select="concat($value, '.value()')"/> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1216,19 +1299,19 @@ <xsl:when test="$safearray='yes'"> <xsl:choose> <xsl:when test="$idltype='boolean'"> - <xsl:value-of select="concat('Helper.unwrapBoolean(',$value,')')"/> + <xsl:value-of select="concat('Helper.unwrapBoolean(', $value, ')')"/> </xsl:when> <xsl:when test="($idltype='long') or ($idltype='unsigned long') or ($idltype='integer')"> - <xsl:value-of select="concat('Helper.unwrapInteger(',$value,')')"/> + <xsl:value-of select="concat('Helper.unwrapInteger(', $value, ')')"/> </xsl:when> <xsl:when test="($idltype='short') or ($idltype='unsigned short')"> - <xsl:value-of select="concat('Helper.unwrapUShort(',$value,')')"/> + <xsl:value-of select="concat('Helper.unwrapUShort(', $value, ')')"/> </xsl:when> <xsl:when test="($idltype='unsigned long long') or ($idltype='long long')"> - <xsl:value-of select="concat('Helper.unwrapULong(',$value,')')"/> + <xsl:value-of select="concat('Helper.unwrapULong(', $value, ')')"/> </xsl:when> <xsl:when test="($idltype='wstring') or ($idltype='uuid')"> - <xsl:value-of select="concat('Helper.unwrapStr(',$value,')')"/> + <xsl:value-of select="concat('Helper.unwrapStr(', $value, ')')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$value"/> @@ -1283,21 +1366,21 @@ <xsl:with-param name="forceelem" select="'yes'" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat('Helper.unwrap2(',$elemgluetype, '.class, ', $elembacktype, '.class, ', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrap2(', $elemgluetype, '.class, ', $elembacktype, '.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('(', $value, ' != null) ? ', $value, '.getTypedWrapped() : null')" /> + <xsl:value-of select="concat('(', $value, ' != null) ? ', $value, '.getTypedWrapped() : null')" /> </xsl:otherwise> </xsl:choose> </xsl:when> - <xsl:when test="$idltype='$unknown'"> - <xsl:choose> + <xsl:when test="$idltype='$unknown'"> + <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrap2(',$elemgluetype, '.class, Dispatch.class, ', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrap2(', $elemgluetype, '.class, Dispatch.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('(', $value, ' != null) ? (Dispatch)', $value, '.getWrapped() : null')" /> + <xsl:value-of select="concat('(', $value, ' != null) ? (Dispatch)', $value, '.getWrapped() : null')" /> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1305,10 +1388,10 @@ <xsl:when test="//enum[@name=$idltype]"> <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrapEnum(', $elemgluetype, '.class,',$value,')')"/> + <xsl:value-of select="concat('Helper.unwrapEnum(', $elemgluetype, '.class, ', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat($value,'.value()')"/> + <xsl:value-of select="concat($value, '.value()')"/> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1316,10 +1399,10 @@ <xsl:when test="$idltype='boolean'"> <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrapBool(', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrapBool(', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('new Variant(',$value,')')"/> + <xsl:value-of select="concat('new Variant(', $value, ')')"/> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1327,10 +1410,10 @@ <xsl:when test="($idltype='short') or ($idltype='unsigned short')"> <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrapShort(', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrapShort(', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('new Variant(',$value,')')"/> + <xsl:value-of select="concat('new Variant(', $value, ')')"/> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1339,10 +1422,10 @@ <xsl:when test="($idltype='long') or ($idltype='unsigned long')"> <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrapInt(', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrapInt(', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('new Variant(',$value,')')"/> + <xsl:value-of select="concat('new Variant(', $value, ')')"/> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1350,10 +1433,10 @@ <xsl:when test="($idltype='wstring') or ($idltype='uuid')"> <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrapString(', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrapString(', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('new Variant(',$value,')')"/> + <xsl:value-of select="concat('new Variant(', $value, ')')"/> </xsl:otherwise> </xsl:choose> </xsl:when> @@ -1361,16 +1444,16 @@ <xsl:when test="($idltype='unsigned long long') or ($idltype='long long')"> <xsl:choose> <xsl:when test="$safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrapLong(', $value,')')"/> + <xsl:value-of select="concat('Helper.unwrapLong(', $value, ')')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat('new Variant(',$value,'.longValue())')"/> + <xsl:value-of select="concat('new Variant(', $value, '.longValue())')"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="($idltype='octet') and ($safearray='yes')"> - <xsl:value-of select="concat('Helper.encodeBase64(', $value,')')"/> + <xsl:value-of select="concat('Helper.encodeBase64(', $value, ')')"/> </xsl:when> <xsl:otherwise> @@ -1407,49 +1490,49 @@ </xsl:variable> <xsl:choose> - <xsl:when test="//interface[@name=$idltype] or $idltype='$unknown'"> + <xsl:when test="//interface[@name=$idltype] or $idltype='$unknown'"> <xsl:choose> <xsl:when test="@safearray='yes'"> - <xsl:value-of select="concat('Helper.unwrap(',$value,')')"/> + <xsl:value-of select="concat('Helper.unwrap(', $value, ')')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="concat('((', $value, ' == null) ? null :', $value, '.getWrapped())')" /> </xsl:otherwise> </xsl:choose> - </xsl:when> - - <xsl:when test="//enum[@name=$idltype]"> - <xsl:choose> - <xsl:when test="$safearray='yes'"> - <xsl:variable name="elembacktype"> - <xsl:call-template name="typeIdl2Back"> - <xsl:with-param name="type" select="$idltype" /> - <xsl:with-param name="safearray" select="'no'" /> - <xsl:with-param name="forceelem" select="'yes'" /> - </xsl:call-template> - </xsl:variable> - <xsl:value-of select="concat('Helper.convertEnums(', $elemgluetype, '.class,', $elembacktype, '.class,', $value,')')"/> - </xsl:when> - <xsl:otherwise> - <xsl:variable name="backtype"> - <xsl:call-template name="typeIdl2Back"> - <xsl:with-param name="type" select="$idltype" /> - <xsl:with-param name="safearray" select="'no'" /> - <xsl:with-param name="forceelem" select="'yes'" /> - </xsl:call-template> - </xsl:variable> - <xsl:value-of select="concat($backtype, '.fromValue(', $value, '.name())')"/> - </xsl:otherwise> - </xsl:choose> - </xsl:when> - - <xsl:when test="($idltype='octet') and ($safearray='yes')"> - <xsl:value-of select="concat('Helper.encodeBase64(',$value,')')"/> - </xsl:when> - - <xsl:otherwise> - <xsl:value-of select="$value"/> - </xsl:otherwise> + </xsl:when> + + <xsl:when test="//enum[@name=$idltype]"> + <xsl:choose> + <xsl:when test="$safearray='yes'"> + <xsl:variable name="elembacktype"> + <xsl:call-template name="typeIdl2Back"> + <xsl:with-param name="type" select="$idltype" /> + <xsl:with-param name="safearray" select="'no'" /> + <xsl:with-param name="forceelem" select="'yes'" /> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="concat('Helper.convertEnums(', $elemgluetype, '.class, ', $elembacktype, '.class, ', $value, ')')"/> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="backtype"> + <xsl:call-template name="typeIdl2Back"> + <xsl:with-param name="type" select="$idltype" /> + <xsl:with-param name="safearray" select="'no'" /> + <xsl:with-param name="forceelem" select="'yes'" /> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="concat($backtype, '.fromValue(', $value, '.name())')"/> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + + <xsl:when test="($idltype='octet') and ($safearray='yes')"> + <xsl:value-of select="concat('Helper.encodeBase64(', $value, ')')"/> + </xsl:when> + + <xsl:otherwise> + <xsl:value-of select="$value"/> + </xsl:otherwise> </xsl:choose> </xsl:template> @@ -1496,150 +1579,150 @@ <xsl:choose> <xsl:when test="($G_vboxGlueStyle='xpcom')"> - <xsl:value-of select="' '" /> + <xsl:text> </xsl:text> <xsl:if test="param[@dir='return']"> <xsl:value-of select="concat($retval, ' = ')" /> </xsl:if> - <xsl:value-of select="concat('getTypedWrapped().', $methodname,'(')"/> + <xsl:value-of select="concat('getTypedWrapped().', $methodname, '(')"/> <xsl:for-each select="param"> - <xsl:choose> - <xsl:when test="@dir='return'"> - <xsl:if test="@safearray='yes'"> - <xsl:value-of select="'null'" /> - </xsl:if> - </xsl:when> - <xsl:when test="@dir='out'"> - <xsl:if test="@safearray='yes'"> - <xsl:value-of select="'null, '" /> - </xsl:if> - <xsl:value-of select="concat('tmp_', @name)" /> - </xsl:when> - <xsl:when test="@dir='in'"> - <xsl:if test="(@safearray='yes') and not(@type = 'octet')"> - <xsl:value-of select="concat(@name,'.size(), ')" /> - </xsl:if> - <xsl:variable name="unwrapped"> - <xsl:call-template name="cookInParam"> - <xsl:with-param name="value" select="@name" /> - <xsl:with-param name="idltype" select="@type" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:variable> - <xsl:value-of select="$unwrapped"/> - </xsl:when> - <xsl:otherwise> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="concat('Unsupported param dir: ', @dir, '".')" /> + <xsl:choose> + <xsl:when test="@dir='return'"> + <xsl:if test="@safearray='yes'"> + <xsl:text>null</xsl:text> + </xsl:if> + </xsl:when> + <xsl:when test="@dir='out'"> + <xsl:if test="@safearray='yes'"> + <xsl:text>null, </xsl:text> + </xsl:if> + <xsl:value-of select="concat('tmp_', @name)" /> + </xsl:when> + <xsl:when test="@dir='in'"> + <xsl:if test="(@safearray='yes') and not(@type = 'octet')"> + <xsl:value-of select="concat(@name, ' != null ? ', @name, '.size() : 0, ')" /> + </xsl:if> + <xsl:variable name="unwrapped"> + <xsl:call-template name="cookInParam"> + <xsl:with-param name="value" select="@name" /> + <xsl:with-param name="idltype" select="@type" /> + <xsl:with-param name="safearray" select="@safearray" /> </xsl:call-template> - </xsl:otherwise> - </xsl:choose> - <xsl:if test="not(position()=last()) and not(following-sibling::param[1]/@dir='return' and not(following-sibling::param[1]/@safearray='yes'))"> - <xsl:value-of select="', '"/> - </xsl:if> + </xsl:variable> + <xsl:value-of select="$unwrapped"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="concat('Unsupported param dir: ', @dir, '".')" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="not(position()=last()) and not(following-sibling::param[1]/@dir='return' and not(following-sibling::param[1]/@safearray='yes'))"> + <xsl:text>, </xsl:text> + </xsl:if> </xsl:for-each> - <xsl:value-of select="'); '"/> + <xsl:text>); </xsl:text> </xsl:when> <xsl:when test="($G_vboxGlueStyle='mscom')"> - <xsl:value-of select="' '" /> + <xsl:text> </xsl:text> <xsl:if test="param[@dir='return']"> <xsl:value-of select="concat($retval, ' = ')" /> </xsl:if> - <xsl:value-of select="concat('Helper.invoke(getTypedWrapped(), "', $methodname, '" ')"/> + <xsl:value-of select="concat('Helper.invoke(getTypedWrapped(), "', $methodname, '" ')"/> <xsl:for-each select="param[not(@dir='return')]"> - <xsl:value-of select="', '"/> + <xsl:text>, </xsl:text> <xsl:choose> - <xsl:when test="@dir='out'"> - <xsl:value-of select="concat('tmp_', @name)" /> - </xsl:when> - <xsl:when test="@dir='in'"> - <xsl:variable name="unwrapped"> - <xsl:call-template name="cookInParam"> - <xsl:with-param name="value" select="@name" /> - <xsl:with-param name="idltype" select="@type" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:variable> - <xsl:value-of select="$unwrapped"/> - </xsl:when> + <xsl:when test="@dir='out'"> + <xsl:value-of select="concat('tmp_', @name)" /> + </xsl:when> + <xsl:when test="@dir='in'"> + <xsl:variable name="unwrapped"> + <xsl:call-template name="cookInParam"> + <xsl:with-param name="value" select="@name" /> + <xsl:with-param name="idltype" select="@type" /> + <xsl:with-param name="safearray" select="@safearray" /> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="$unwrapped"/> + </xsl:when> </xsl:choose> </xsl:for-each> - <xsl:value-of select="'); '"/> + <xsl:text>); </xsl:text> </xsl:when> - <xsl:when test="($G_vboxGlueStyle='jaxws')"> - <xsl:variable name="jaxwsmethod"> - <xsl:call-template name="makeJaxwsMethod"> - <xsl:with-param name="ifname" select="$ifname" /> - <xsl:with-param name="methodname" select="$methodname" /> - </xsl:call-template> - </xsl:variable> - <xsl:variable name="portArg"> - <xsl:if test="not(//interface[@name=$ifname]/@wsmap='global')"> - <xsl:value-of select="'obj'"/> - </xsl:if> - </xsl:variable> - <xsl:variable name="paramsinout" select="param[@dir='in' or @dir='out']" /> - - <xsl:value-of select="' '" /> - <xsl:if test="param[@dir='return'] and not(param[@dir='out'])"> - <xsl:value-of select="concat($retval, ' = ')" /> - </xsl:if> - <xsl:value-of select="concat('port.', $jaxwsmethod, '(', $portArg)" /> - <xsl:if test="$paramsinout and not($portArg='')"> - <xsl:value-of select="', '"/> - </xsl:if> - - <!-- jax-ws has an oddity: if both out params and a return value exist, - then the return value is moved to the function's argument list... --> - <xsl:choose> - <xsl:when test="param[@dir='out'] and param[@dir='return']"> - <xsl:for-each select="param"> - <xsl:choose> - <xsl:when test="@dir='return'"> - <xsl:value-of select="$retval"/> - </xsl:when> - <xsl:when test="@dir='out'"> - <xsl:value-of select="concat('tmp_', @name)" /> - </xsl:when> - <xsl:otherwise> - <xsl:call-template name="cookInParam"> - <xsl:with-param name="value" select="@name" /> - <xsl:with-param name="idltype" select="@type" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:otherwise> - </xsl:choose> - <xsl:if test="not(position()=last())"> - <xsl:value-of select="', '"/> - </xsl:if> - </xsl:for-each> - </xsl:when> - <xsl:otherwise> - <xsl:for-each select="$paramsinout"> - <xsl:choose> - <xsl:when test="@dir='return'"> - <xsl:value-of select="$retval"/> - </xsl:when> - <xsl:when test="@dir='out'"> - <xsl:value-of select="concat('tmp_', @name)" /> - </xsl:when> - <xsl:otherwise> - <xsl:call-template name="cookInParam"> - <xsl:with-param name="value" select="@name" /> - <xsl:with-param name="idltype" select="@type" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:otherwise> - </xsl:choose> - <xsl:if test="not(position()=last())"> - <xsl:value-of select="', '"/> - </xsl:if> - </xsl:for-each> - </xsl:otherwise> - </xsl:choose> - <xsl:value-of select="'); '"/> - </xsl:when> + <xsl:when test="($G_vboxGlueStyle='jaxws')"> + <xsl:variable name="jaxwsmethod"> + <xsl:call-template name="makeJaxwsMethod"> + <xsl:with-param name="ifname" select="$ifname" /> + <xsl:with-param name="methodname" select="$methodname" /> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="portArg"> + <xsl:if test="not(//interface[@name=$ifname]/@wsmap='global')"> + <xsl:text>obj</xsl:text> + </xsl:if> + </xsl:variable> + <xsl:variable name="paramsinout" select="param[@dir='in' or @dir='out']" /> + + <xsl:text> </xsl:text> + <xsl:if test="param[@dir='return'] and not(param[@dir='out'])"> + <xsl:value-of select="concat($retval, ' = ')" /> + </xsl:if> + <xsl:value-of select="concat('port.', $jaxwsmethod, '(', $portArg)" /> + <xsl:if test="$paramsinout and not($portArg='')"> + <xsl:text>, </xsl:text> + </xsl:if> + + <!-- jax-ws has an oddity: if both out params and a return value exist, + then the return value is moved to the function's argument list... --> + <xsl:choose> + <xsl:when test="param[@dir='out'] and param[@dir='return']"> + <xsl:for-each select="param"> + <xsl:choose> + <xsl:when test="@dir='return'"> + <xsl:value-of select="$retval"/> + </xsl:when> + <xsl:when test="@dir='out'"> + <xsl:value-of select="concat('tmp_', @name)" /> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="cookInParam"> + <xsl:with-param name="value" select="@name" /> + <xsl:with-param name="idltype" select="@type" /> + <xsl:with-param name="safearray" select="@safearray" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="not(position()=last())"> + <xsl:text>, </xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:when> + <xsl:otherwise> + <xsl:for-each select="$paramsinout"> + <xsl:choose> + <xsl:when test="@dir='return'"> + <xsl:value-of select="$retval"/> + </xsl:when> + <xsl:when test="@dir='out'"> + <xsl:value-of select="concat('tmp_', @name)" /> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="cookInParam"> + <xsl:with-param name="value" select="@name" /> + <xsl:with-param name="idltype" select="@type" /> + <xsl:with-param name="safearray" select="@safearray" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="not(position()=last())"> + <xsl:text>, </xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:otherwise> + </xsl:choose> + <xsl:text>); </xsl:text> + </xsl:when> <xsl:otherwise> <xsl:call-template name="fatalError"> @@ -1657,35 +1740,33 @@ <xsl:param name="retval"/> <xsl:choose> + <xsl:when test="$G_vboxGlueStyle='xpcom'"> + <xsl:value-of select="concat(' ', $backtype, ' ', $retval, ' = getTypedWrapped().', $gettername, '(')" /> + <xsl:if test="@safearray"> + <xsl:text>null</xsl:text> + </xsl:if> + <xsl:text>); </xsl:text> + </xsl:when> - <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="concat(' ', $backtype, ' ', $retval,' = getTypedWrapped().', $gettername,'(')" /> - <xsl:if test="@safearray"> - <xsl:value-of select="'null'" /> - </xsl:if> - <xsl:value-of select="'); '" /> - </xsl:when> - - <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="concat(' ', $backtype, ' ', $retval,' = Dispatch.get(getTypedWrapped(), "', @name,'"); ')" /> - </xsl:when> - - <xsl:when test="$G_vboxGlueStyle='jaxws'"> - <xsl:variable name="jaxwsGetter"> - <xsl:call-template name="makeJaxwsMethod"> - <xsl:with-param name="ifname" select="$ifname" /> - <xsl:with-param name="methodname" select="$gettername" /> - </xsl:call-template> - </xsl:variable> - <xsl:value-of select="concat(' ', $backtype, ' ', $retval,' = port.', $jaxwsGetter, '(obj); ')" /> - </xsl:when> - - <xsl:otherwise> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="'Style unknown (genGetterCall)'" /> - </xsl:call-template> - </xsl:otherwise> + <xsl:when test="$G_vboxGlueStyle='mscom'"> + <xsl:value-of select="concat(' ', $backtype, ' ', $retval, ' = Dispatch.get(getTypedWrapped(), "', @name, '"); ')" /> + </xsl:when> + + <xsl:when test="$G_vboxGlueStyle='jaxws'"> + <xsl:variable name="jaxwsGetter"> + <xsl:call-template name="makeJaxwsMethod"> + <xsl:with-param name="ifname" select="$ifname" /> + <xsl:with-param name="methodname" select="$gettername" /> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="concat(' ', $backtype, ' ', $retval, ' = port.', $jaxwsGetter, '(obj); ')" /> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="'Style unknown (genGetterCall)'" /> + </xsl:call-template> + </xsl:otherwise> </xsl:choose> </xsl:template> @@ -1695,104 +1776,111 @@ <xsl:param name="value"/> <xsl:choose> - <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="concat(' getTypedWrapped().', $settername, '(', $value,'); ')" /> - </xsl:when> + <xsl:when test="$G_vboxGlueStyle='xpcom'"> + <xsl:value-of select="concat(' getTypedWrapped().', $settername, '(', $value, '); ')" /> + </xsl:when> - <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="concat(' Dispatch.put(getTypedWrapped(), "', @name,'", ',$value, '); ')" /> - </xsl:when> + <xsl:when test="$G_vboxGlueStyle='mscom'"> + <xsl:value-of select="concat(' Dispatch.put(getTypedWrapped(), "', @name, '", ', $value, '); ')" /> + </xsl:when> - <xsl:when test="$G_vboxGlueStyle='jaxws'"> + <xsl:when test="$G_vboxGlueStyle='jaxws'"> <xsl:variable name="jaxwsSetter"> <xsl:call-template name="makeJaxwsMethod"> <xsl:with-param name="ifname" select="$ifname" /> <xsl:with-param name="methodname" select="$settername" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat(' port.', $jaxwsSetter, '(obj, ', $value,'); ')" /> - </xsl:when> - - <xsl:otherwise> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="'Style unknown (genSetterCall)'" /> - </xsl:call-template> - </xsl:otherwise> + <xsl:value-of select="concat(' port.', $jaxwsSetter, '(obj, ', $value, '); ')" /> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="'Style unknown (genSetterCall)'" /> + </xsl:call-template> + </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="genStructWrapperJaxws"> <xsl:param name="ifname"/> - <xsl:value-of select="concat(' private ', $G_virtualBoxPackageCom,'.',$ifname, ' real; ')"/> - <xsl:value-of select="' private VboxPortType port; '"/> + <xsl:value-of select="concat(' private ', $G_virtualBoxPackageCom, '.', $ifname, ' real; ')"/> + <xsl:text> private VboxPortType port; </xsl:text> - <xsl:value-of select="concat(' public ', $ifname, '(', $G_virtualBoxPackageCom,'.',$ifname,' real, VboxPortType port) { this.real = real; this.port = port; } ')"/> + <xsl:value-of select="concat(' public ', $ifname, '(', $G_virtualBoxPackageCom, '.', $ifname, ' real, VboxPortType port) ')" /> + <xsl:text> { </xsl:text> + <xsl:text> this.real = real; </xsl:text> + <xsl:text> this.port = port; </xsl:text> + <xsl:text> } </xsl:text> <xsl:for-each select="attribute"> <xsl:variable name="attrname"><xsl:value-of select="@name" /></xsl:variable> <xsl:variable name="attrtype"><xsl:value-of select="@type" /></xsl:variable> - <xsl:variable name="attrreadonly"><xsl:value-of select="@readonly" /></xsl:variable> <xsl:variable name="attrsafearray"><xsl:value-of select="@safearray" /></xsl:variable> - <xsl:if test="not($attrreadonly)"> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="'Non read-only struct (genStructWrapperJaxws)'" /> - </xsl:call-template> - </xsl:if> + <xsl:if test="not(@wsmap = 'suppress')"> - <!-- Emit getter --> - <xsl:variable name="backgettername"> - <xsl:choose> - <!-- Stupid, but backend boolean getters called isFoo(), not getFoo() --> - <xsl:when test="$attrtype = 'boolean'"> - <xsl:variable name="capsname"> - <xsl:call-template name="capitalize"> - <xsl:with-param name="str" select="$attrname" /> + <xsl:if test="not(@readonly = 'yes')"> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="concat('Non read-only struct (genStructWrapperJaxws) in interface ', $ifname, ', attribute ', $attrname)" /> + </xsl:call-template> + </xsl:if> + + <!-- Emit getter --> + <xsl:variable name="backgettername"> + <xsl:choose> + <!-- Stupid, but backend boolean getters called isFoo(), not getFoo() --> + <xsl:when test="$attrtype = 'boolean'"> + <xsl:variable name="capsname"> + <xsl:call-template name="capitalize"> + <xsl:with-param name="str" select="$attrname" /> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="concat('is', $capsname)" /> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="makeGetterName"> + <xsl:with-param name="attrname" select="$attrname" /> </xsl:call-template> - </xsl:variable> - <xsl:value-of select="concat('is', $capsname)" /> - </xsl:when> - <xsl:otherwise> - <xsl:call-template name="makeGetterName"> - <xsl:with-param name="attrname" select="$attrname" /> - </xsl:call-template> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> - <xsl:variable name="gluegettername"> - <xsl:call-template name="makeGetterName"> - <xsl:with-param name="attrname" select="$attrname" /> - </xsl:call-template> - </xsl:variable> + <xsl:variable name="gluegettername"> + <xsl:call-template name="makeGetterName"> + <xsl:with-param name="attrname" select="$attrname" /> + </xsl:call-template> + </xsl:variable> - <xsl:variable name="gluegettertype"> - <xsl:call-template name="typeIdl2Glue"> - <xsl:with-param name="type" select="$attrtype" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:variable> + <xsl:variable name="gluegettertype"> + <xsl:call-template name="typeIdl2Glue"> + <xsl:with-param name="type" select="$attrtype" /> + <xsl:with-param name="safearray" select="@safearray" /> + </xsl:call-template> + </xsl:variable> - <xsl:variable name="backgettertype"> - <xsl:call-template name="typeIdl2Back"> - <xsl:with-param name="type" select="$attrtype" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:variable> - - <xsl:value-of select="concat(' public ', $gluegettertype, ' ', $gluegettername, '() { ')" /> - <xsl:value-of select="concat(' ', $backgettertype, ' retVal = real.', $backgettername, '(); ')" /> - <xsl:variable name="wrapped"> - <xsl:call-template name="cookOutParam"> - <xsl:with-param name="value" select="'retVal'" /> - <xsl:with-param name="idltype" select="$attrtype" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:variable> - <xsl:value-of select="concat(' return ', $wrapped, '; ')" /> - <xsl:value-of select=" ' } '" /> + <xsl:variable name="backgettertype"> + <xsl:call-template name="typeIdl2Back"> + <xsl:with-param name="type" select="$attrtype" /> + <xsl:with-param name="safearray" select="@safearray" /> + </xsl:call-template> + </xsl:variable> + + <xsl:apply-templates select="desc" mode="attribute_get"/> + <xsl:value-of select="concat(' public ', $gluegettertype, ' ', $gluegettername, '() ')" /> + <xsl:text> { </xsl:text> + <xsl:value-of select="concat(' ', $backgettertype, ' retVal = real.', $backgettername, '(); ')" /> + <xsl:variable name="wrapped"> + <xsl:call-template name="cookOutParam"> + <xsl:with-param name="value" select="'retVal'" /> + <xsl:with-param name="idltype" select="$attrtype" /> + <xsl:with-param name="safearray" select="@safearray" /> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="concat(' return ', $wrapped, '; ')" /> + <xsl:text> } </xsl:text> + </xsl:if> </xsl:for-each> @@ -1805,9 +1893,10 @@ <xsl:choose> <xsl:when test="(param[@mod='ptr']) or (($G_vboxGlueStyle='jaxws') and (param[@type=($G_setSuppressedInterfaces/@name)]))" > - <xsl:comment> - <xsl:value-of select="concat('Skipping method ', $methodname, ' for it has parameters with suppressed types')" /> - </xsl:comment> + <xsl:value-of select="concat(' // Skipping method ', $methodname, ' for it has parameters with suppressed types ')" /> + </xsl:when> + <xsl:when test="($G_vboxGlueStyle='jaxws') and (@wsmap = 'suppress')" > + <xsl:value-of select="concat(' // Skipping method ', $methodname, ' for it is suppressed ')" /> </xsl:when> <xsl:otherwise> <xsl:variable name="hasReturnParms" select="param[@dir='return']" /> @@ -1830,10 +1919,10 @@ <xsl:variable name="retValValue"> <xsl:choose> <xsl:when test="(param[@dir='out']) and ($G_vboxGlueStyle='jaxws')"> - <xsl:value-of select="'retVal.value'"/> + <xsl:text>retVal.value</xsl:text> </xsl:when> <xsl:otherwise> - <xsl:value-of select="'retVal'"/> + <xsl:text>retVal</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:variable> @@ -1856,10 +1945,11 @@ </xsl:otherwise> </xsl:choose> <xsl:if test="not(position()=last())"> - <xsl:value-of select="', '" /> + <xsl:text>, </xsl:text> </xsl:if> </xsl:for-each> - <xsl:value-of select="') { '"/> + <xsl:text>) </xsl:text> + <xsl:text> { </xsl:text> <xsl:call-template name="startExcWrapper"/> @@ -1873,13 +1963,13 @@ </xsl:variable> <xsl:choose> <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="concat(' ', $backouttype, '[] tmp_', @name, ' = (', $backouttype, '[])java.lang.reflect.Array.newInstance(',$backouttype,'.class, 1); ')"/> + <xsl:value-of select="concat(' ', $backouttype, '[] tmp_', @name, ' = (', $backouttype, '[])java.lang.reflect.Array.newInstance(', $backouttype, '.class, 1); ')"/> </xsl:when> <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="concat(' Variant tmp_', @name, ' = new Variant(); ')"/> + <xsl:value-of select="concat(' Variant tmp_', @name, ' = new Variant(); ')"/> </xsl:when> <xsl:when test="$G_vboxGlueStyle='jaxws'"> - <xsl:value-of select="concat(' javax.xml.ws.Holder<', $backouttype,'> tmp_', @name, ' = new javax.xml.ws.Holder<', $backouttype,'>(); ')"/> + <xsl:value-of select="concat(' javax.xml.ws.Holder<', $backouttype, '> tmp_', @name, ' = new javax.xml.ws.Holder<', $backouttype, '>(); ')"/> </xsl:when> <xsl:otherwise> <xsl:call-template name="fatalError"> @@ -1904,7 +1994,7 @@ '>(); ')"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat(' ', $backrettype, ' retVal; ')"/> + <xsl:value-of select="concat(' ', $backrettype, ' retVal; ')"/> </xsl:otherwise> </xsl:choose> </xsl:if> @@ -1916,18 +2006,18 @@ <xsl:with-param name="retval" select="'retVal'" /> </xsl:call-template> - <!-- return out params --> + <!-- return out params --> <xsl:for-each select="param[@dir='out']"> <xsl:variable name="varval"> <xsl:choose> <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="concat('tmp_',@name,'[0]')" /> + <xsl:value-of select="concat('tmp_', @name, '[0]')" /> </xsl:when> <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="concat('tmp_',@name)" /> + <xsl:value-of select="concat('tmp_', @name)" /> </xsl:when> <xsl:when test="$G_vboxGlueStyle='jaxws'"> - <xsl:value-of select="concat('tmp_',@name,'.value')" /> + <xsl:value-of select="concat('tmp_', @name, '.value')" /> </xsl:when> <xsl:otherwise> <xsl:call-template name="fatalError"> @@ -1943,7 +2033,7 @@ <xsl:with-param name="safearray" select="@safearray" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat(' ', @name, '.value = ',$wrapped,'; ')"/> + <xsl:value-of select="concat(' ', @name, '.value = ', $wrapped, '; ')"/> </xsl:for-each> <xsl:if test="$hasReturnParms"> @@ -1959,7 +2049,7 @@ </xsl:if> <xsl:call-template name="endExcWrapper"/> - <xsl:value-of select="' } '"/> + <xsl:text> } </xsl:text> </xsl:otherwise> </xsl:choose> @@ -1972,9 +2062,7 @@ <xsl:choose> <xsl:when test="(param[@mod='ptr'])" > - <xsl:comment> - <xsl:value-of select="concat('Skipping method ', $methodname, ' for it has parameters with suppressed types')" /> - </xsl:comment> + <xsl:value-of select="concat(' // Skipping method ', $methodname, ' for it has parameters with suppressed types ')" /> </xsl:when> <xsl:otherwise> <xsl:variable name="returnidltype" select="param[@dir='return']/@type" /> @@ -2013,7 +2101,7 @@ <xsl:text>, </xsl:text> </xsl:if> </xsl:for-each> - <xsl:value-of select="'); '"/> + <xsl:text>); </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> @@ -2023,7 +2111,8 @@ <xsl:param name="ifname"/> <xsl:param name="uuid" /> - <xsl:value-of select="concat(' public static ', $ifname, ' queryInterface(IUnknown obj) { ')" /> + <xsl:value-of select="concat(' public static ', $ifname, ' queryInterface(IUnknown obj) ')" /> + <xsl:text> { </xsl:text> <xsl:choose> <xsl:when test="$G_vboxGlueStyle='xpcom'"> <xsl:variable name="backtype"> @@ -2031,9 +2120,9 @@ <xsl:with-param name="type" select="$ifname" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select=" ' nsISupports nsobj = obj != null ? (nsISupports)obj.getWrapped() : null; '"/> - <xsl:value-of select=" ' if (nsobj == null) return null; '"/> - <xsl:value-of select="concat(' ',$backtype, ' qiobj = Helper.queryInterface(nsobj, "{',$uuid,'}", ',$backtype,'.class); ')" /> + <xsl:text> nsISupports nsobj = obj != null ? (nsISupports)obj.getWrapped() : null; </xsl:text> + <xsl:text> if (nsobj == null) return null; </xsl:text> + <xsl:value-of select="concat(' ', $backtype, ' qiobj = Helper.queryInterface(nsobj, "{', $uuid, '}", ', $backtype, '.class); ')" /> <xsl:value-of select="concat(' return qiobj == null ? null : new ', $ifname, '(qiobj); ')" /> </xsl:when> @@ -2053,7 +2142,7 @@ </xsl:otherwise> </xsl:choose> - <xsl:value-of select=" ' } '" /> + <xsl:text> } </xsl:text> </xsl:template> @@ -2063,9 +2152,7 @@ <xsl:choose> <xsl:when test="(param[@mod='ptr'])" > - <xsl:comment> - <xsl:value-of select="concat('Skipping method ', $methodname, ' for it has parameters with suppressed types')" /> - </xsl:comment> + <xsl:value-of select="concat(' // Skipping method ', $methodname, ' for it has parameters with suppressed types ')" /> </xsl:when> <xsl:otherwise> <xsl:variable name="hasReturnParms" select="param[@dir='return']" /> @@ -2102,7 +2189,7 @@ </xsl:when> <xsl:otherwise> <xsl:if test="@safearray"> - <xsl:value-of select="concat('long len_',@name,', ')" /> + <xsl:value-of select="concat('long len_', @name, ', ')" /> </xsl:if> <xsl:value-of select="concat($parambacktype, ' ', @name)" /> </xsl:otherwise> @@ -2111,7 +2198,8 @@ <xsl:text>, </xsl:text> </xsl:if> </xsl:for-each> - <xsl:value-of select="') { '"/> + <xsl:text>) </xsl:text> + <xsl:text> { </xsl:text> </xsl:when> <xsl:when test="$G_vboxGlueStyle='mscom'"> @@ -2121,8 +2209,8 @@ </xsl:call-template> </xsl:variable> <xsl:value-of select="concat(' public ', $returnbacktype, ' ', $capsname, '(')" /> - <xsl:value-of select="'Variant _args[]'"/> - <xsl:value-of select="') { '"/> + <xsl:text>Variant _args[]) </xsl:text> + <xsl:text> { </xsl:text> <xsl:for-each select="exsl:node-set($paramsinout)"> <xsl:variable name="parambacktype"> <xsl:call-template name="typeIdl2Back"> @@ -2130,16 +2218,15 @@ <xsl:with-param name="safearray" select="@safearray" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat(' ', $parambacktype, ' ', @name, '=_args[', count(preceding-sibling::param),']; ')" /> + <xsl:value-of select="concat(' ', $parambacktype, ' ', @name, '=_args[', count(preceding-sibling::param), ']; ')" /> </xsl:for-each> </xsl:when> - <xsl:otherwise> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="'Style unknown (genSetterCall)'" /> - </xsl:call-template> - </xsl:otherwise> - + <xsl:otherwise> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="'Style unknown (genSetterCall)'" /> + </xsl:call-template> + </xsl:otherwise> </xsl:choose> <!-- declare temp out params --> @@ -2165,50 +2252,50 @@ </xsl:if> <!-- Method call --> - <xsl:value-of select="concat(' sink.', $methodname,'(')"/> + <xsl:value-of select="concat(' sink.', $methodname, '(')"/> <xsl:for-each select="param[not(@dir='return')]"> - <xsl:choose> - <xsl:when test="@dir='out'"> - <xsl:value-of select="concat('tmp_', @name)" /> - </xsl:when> - <xsl:when test="@dir='in'"> - <xsl:variable name="wrapped"> - <xsl:call-template name="cookOutParam"> - <xsl:with-param name="value" select="@name" /> - <xsl:with-param name="idltype" select="@type" /> - <xsl:with-param name="safearray" select="@safearray" /> - </xsl:call-template> - </xsl:variable> - <xsl:value-of select="$wrapped"/> - </xsl:when> - <xsl:otherwise> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="concat('Unsupported param dir: ', @dir, '".')" /> + <xsl:choose> + <xsl:when test="@dir='out'"> + <xsl:value-of select="concat('tmp_', @name)" /> + </xsl:when> + <xsl:when test="@dir='in'"> + <xsl:variable name="wrapped"> + <xsl:call-template name="cookOutParam"> + <xsl:with-param name="value" select="@name" /> + <xsl:with-param name="idltype" select="@type" /> + <xsl:with-param name="safearray" select="@safearray" /> </xsl:call-template> - </xsl:otherwise> - </xsl:choose> - <xsl:if test="not(position()=last())"> - <xsl:value-of select="', '"/> - </xsl:if> + </xsl:variable> + <xsl:value-of select="$wrapped"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="concat('Unsupported param dir: ', @dir, '".')" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="not(position()=last())"> + <xsl:text>, </xsl:text> + </xsl:if> </xsl:for-each> - <xsl:value-of select="'); '"/> + <xsl:text>); </xsl:text> - <!-- return out params --> + <!-- return out params --> <xsl:for-each select="param[@dir='out']"> <xsl:variable name="unwrapped"> <xsl:call-template name="cookInParam"> - <xsl:with-param name="value" select="concat('tmp_',@name,'.value')" /> + <xsl:with-param name="value" select="concat('tmp_', @name, '.value')" /> <xsl:with-param name="idltype" select="@type" /> <xsl:with-param name="safearray" select="@safearray" /> </xsl:call-template> </xsl:variable> <xsl:choose> <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="concat(' ', @name, '[0] = ',$unwrapped,'; ')"/> + <xsl:value-of select="concat(' ', @name, '[0] = ', $unwrapped, '; ')"/> </xsl:when> <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="concat(' _args[',count(preceding-sibling::param),'] = ',$unwrapped,'; ')"/> + <xsl:value-of select="concat(' _args[', count(preceding-sibling::param), '] = ', $unwrapped, '; ')"/> </xsl:when> </xsl:choose> </xsl:for-each> @@ -2224,7 +2311,7 @@ </xsl:variable> <xsl:value-of select="concat(' return ', $unwrapped, '; ')" /> </xsl:if> - <xsl:value-of select="' } '"/> + <xsl:text> } </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> @@ -2242,20 +2329,23 @@ <!-- Constructor --> <xsl:choose> <xsl:when test="($G_vboxGlueStyle='jaxws')"> - <xsl:value-of select="concat(' public ', $ifname, '(String wrapped, VboxPortType port) { ')" /> - <xsl:value-of select=" ' super(wrapped, port); '"/> - <xsl:value-of select=" ' } '"/> + <xsl:value-of select="concat(' public ', $ifname, '(String wrapped, VboxPortType port) ')" /> + <xsl:text> { </xsl:text> + <xsl:text> super(wrapped, port); </xsl:text> + <xsl:text> } </xsl:text> </xsl:when> <xsl:when test="($G_vboxGlueStyle='xpcom') or ($G_vboxGlueStyle='mscom')"> - <xsl:value-of select="concat(' public ', $ifname, '(', $wrappedType,' wrapped) { ')" /> - <xsl:value-of select=" ' super(wrapped); '"/> - <xsl:value-of select=" ' } '"/> + <xsl:value-of select="concat(' public ', $ifname, '(', $wrappedType, ' wrapped) ')" /> + <xsl:text> { </xsl:text> + <xsl:text> super(wrapped); </xsl:text> + <xsl:text> } </xsl:text> <!-- Typed wrapped object accessor --> - <xsl:value-of select="concat(' public ', $wrappedType, ' getTypedWrapped() { ')" /> - <xsl:value-of select="concat(' return (', $wrappedType, ') getWrapped(); ')" /> - <xsl:value-of select=" ' } '" /> + <xsl:value-of select="concat(' public ', $wrappedType, ' getTypedWrapped() ')" /> + <xsl:text> { </xsl:text> + <xsl:value-of select="concat(' return (', $wrappedType, ') getWrapped(); ')" /> + <xsl:text> } </xsl:text> </xsl:when> <xsl:otherwise> @@ -2268,12 +2358,14 @@ <xsl:for-each select="attribute[not(@mod='ptr')]"> <xsl:variable name="attrname"><xsl:value-of select="@name" /></xsl:variable> <xsl:variable name="attrtype"><xsl:value-of select="@type" /></xsl:variable> - <xsl:variable name="attrreadonly"><xsl:value-of select="@readonly" /></xsl:variable> <xsl:variable name="attrsafearray"><xsl:value-of select="@safearray" /></xsl:variable> <xsl:choose> <xsl:when test="($G_vboxGlueStyle='jaxws') and ($attrtype=($G_setSuppressedInterfaces/@name))"> - <xsl:value-of select="concat(' // skip attribute ',$attrname, ' of suppressed type ', $attrtype, ' ')" /> + <xsl:value-of select="concat(' // Skipping attribute ', $attrname, ' of suppressed type ', $attrtype, ' ')" /> + </xsl:when> + <xsl:when test="($G_vboxGlueStyle='jaxws') and (@wsmap = 'suppress')" > + <xsl:value-of select="concat(' // Skipping attribute ', $attrname, ' for it is suppressed ')" /> </xsl:when> <xsl:otherwise> @@ -2303,7 +2395,8 @@ <xsl:with-param name="safearray" select="@safearray" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat(' public ', $gluetype, ' ', $gettername, '() { ')" /> + <xsl:value-of select="concat(' public ', $gluetype, ' ', $gettername, '() ')" /> + <xsl:text> { </xsl:text> <xsl:call-template name="startExcWrapper"/> @@ -2315,11 +2408,11 @@ <xsl:with-param name="retval" select="'retVal'" /> </xsl:call-template> - <xsl:value-of select="concat(' return ', $wrapped, '; ')" /> + <xsl:value-of select="concat(' return ', $wrapped, '; ')" /> <xsl:call-template name="endExcWrapper"/> - <xsl:value-of select= "' } '" /> - <xsl:if test="not(@readonly='yes')"> + <xsl:text> } </xsl:text> + <xsl:if test="not(@readonly = 'yes')"> <!-- emit setter method --> <xsl:apply-templates select="desc" mode="attribute_set"/> <xsl:variable name="settername"><xsl:call-template name="makeSetterName"><xsl:with-param name="attrname" select="$attrname" /></xsl:call-template></xsl:variable> @@ -2331,7 +2424,8 @@ <xsl:with-param name="safearray" select="@safearray" /> </xsl:call-template> </xsl:variable> - <xsl:value-of select="concat(' public void ', $settername, '(', $gluetype, ' value) { ')" /> + <xsl:value-of select="concat(' public void ', $settername, '(', $gluetype, ' value) ')" /> + <xsl:text> { </xsl:text> <xsl:call-template name="startExcWrapper"/> <!-- Actual setter implementation --> <xsl:call-template name="genSetterCall"> @@ -2340,7 +2434,7 @@ <xsl:with-param name="value" select="$unwrapped" /> </xsl:call-template> <xsl:call-template name="endExcWrapper"/> - <xsl:value-of select= "' } '" /> + <xsl:text> } </xsl:text> </xsl:if> </xsl:otherwise> @@ -2375,41 +2469,46 @@ <xsl:with-param name="package" select="$G_virtualBoxPackage" /> </xsl:call-template> - <xsl:text>import java.util.List; </xsl:text> + <xsl:if test="$filelistonly=''"> + <xsl:text>import java.util.List; </xsl:text> - <xsl:apply-templates select="desc" mode="interface"/> + <xsl:apply-templates select="desc" mode="interface"/> - <xsl:choose> - <xsl:when test="($wsmap='struct') and ($G_vboxGlueStyle='jaxws')"> - <xsl:value-of select="concat('public class ', $ifname, ' { ')" /> - <xsl:call-template name="genStructWrapperJaxws"> - <xsl:with-param name="ifname" select="$ifname" /> - </xsl:call-template> - </xsl:when> + <xsl:choose> + <xsl:when test="($wsmap='struct') and ($G_vboxGlueStyle='jaxws')"> + <xsl:value-of select="concat('public class ', $ifname, ' ')" /> + <xsl:text>{ </xsl:text> + <xsl:call-template name="genStructWrapperJaxws"> + <xsl:with-param name="ifname" select="$ifname" /> + </xsl:call-template> + </xsl:when> - <xsl:otherwise> - <xsl:variable name="extends" select="//interface[@name=$ifname]/@extends" /> - <xsl:choose> - <xsl:when test="($extends = '$unknown') or ($extends = '$dispatched') or ($extends = '$errorinfo')"> - <xsl:value-of select="concat('public class ', $ifname, ' extends IUnknown { ')" /> - </xsl:when> - <xsl:when test="//interface[@name=$extends]"> - <xsl:value-of select="concat('public class ', $ifname, ' extends ', $extends, ' { ')" /> - </xsl:when> - <xsl:otherwise> - <xsl:call-template name="fatalError"> - <xsl:with-param name="msg" select="concat('Interface generation: interface "', $ifname, '" has invalid "extends" value ', $extends, '.')" /> - </xsl:call-template> - </xsl:otherwise> - </xsl:choose> - <xsl:call-template name="genIfaceWrapper"> - <xsl:with-param name="ifname" select="$ifname" /> - </xsl:call-template> - </xsl:otherwise> - </xsl:choose> + <xsl:otherwise> + <xsl:variable name="extends" select="//interface[@name=$ifname]/@extends" /> + <xsl:choose> + <xsl:when test="($extends = '$unknown') or ($extends = '$errorinfo')"> + <xsl:value-of select="concat('public class ', $ifname, ' extends IUnknown ')" /> + <xsl:text>{ </xsl:text> + </xsl:when> + <xsl:when test="//interface[@name=$extends]"> + <xsl:value-of select="concat('public class ', $ifname, ' extends ', $extends, ' ')" /> + <xsl:text>{ </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="fatalError"> + <xsl:with-param name="msg" select="concat('Interface generation: interface "', $ifname, '" has invalid "extends" value ', $extends, '.')" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + <xsl:call-template name="genIfaceWrapper"> + <xsl:with-param name="ifname" select="$ifname" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> - <!-- end of class --> - <xsl:value-of select="'} '" /> + <!-- end of class --> + <xsl:text>} </xsl:text> + </xsl:if> <xsl:call-template name="endFile"> <xsl:with-param name="file" select="$filename" /> @@ -2429,7 +2528,8 @@ <xsl:text>import java.util.List; </xsl:text> - <xsl:value-of select="concat('public interface ', $ifname, ' { ')" /> + <xsl:value-of select="concat('public interface ', $ifname, ' ')" /> + <xsl:text>{ </xsl:text> <!-- emit methods declarations--> <xsl:for-each select="method"> @@ -2439,7 +2539,7 @@ </xsl:call-template> </xsl:for-each> - <xsl:value-of select="'} '" /> + <xsl:text>} </xsl:text> <xsl:call-template name="endFile"> <xsl:with-param name="file" select="$filename" /> @@ -2461,19 +2561,22 @@ <!-- emit glue methods body --> <xsl:choose> <xsl:when test="$G_vboxGlueStyle='xpcom'"> - <xsl:value-of select="concat('class ', $ifname, 'Impl extends nsISupportsBase implements ', $backtype, ' { ')" /> + <xsl:value-of select="concat('class ', $ifname, 'Impl extends nsISupportsBase implements ', $backtype, ' ')" /> + <xsl:text>{ </xsl:text> </xsl:when> <xsl:when test="$G_vboxGlueStyle='mscom'"> - <xsl:value-of select="concat('public class ', $ifname, 'Impl { ')" /> + <xsl:value-of select="concat('public class ', $ifname, 'Impl ')" /> + <xsl:text>{ </xsl:text> </xsl:when> </xsl:choose> <xsl:value-of select="concat(' ', $ifname, ' sink; ')" /> - <xsl:value-of select="concat(' ', $ifname, 'Impl(', $ifname,' sink) { ')" /> - <xsl:value-of select="' this.sink = sink; '" /> - <xsl:value-of select="' } '" /> + <xsl:value-of select="concat(' ', $ifname, 'Impl(', $ifname, ' sink) ')" /> + <xsl:text> { </xsl:text> + <xsl:text> this.sink = sink; </xsl:text> + <xsl:text> } </xsl:text> <!-- emit methods implementations --> <xsl:for-each select="method"> @@ -2483,7 +2586,7 @@ </xsl:call-template> </xsl:for-each> - <xsl:value-of select="'} '" /> + <xsl:text>} </xsl:text> <xsl:call-template name="endFile"> <xsl:with-param name="file" select="$filenameimpl" /> @@ -2492,298 +2595,376 @@ <xsl:template name="emitHandwritten"> -<xsl:call-template name="startFile"> + <xsl:call-template name="startFile"> <xsl:with-param name="file" select="'Holder.java'" /> <xsl:with-param name="package" select="$G_virtualBoxPackage" /> </xsl:call-template> - <xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ public class Holder<T> { - public T value; - - public Holder() - { - } - public Holder(T value) - { - this.value = value; - } -} -]]></xsl:text> - - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'Holder.java'" /> - </xsl:call-template> + public T value; -<xsl:call-template name="startFile"> - <xsl:with-param name="file" select="'VBoxException.java'" /> - <xsl:with-param name="package" select="$G_virtualBoxPackage" /> - </xsl:call-template> - - <xsl:text><![CDATA[ -public class VBoxException extends RuntimeException -{ - private Throwable wrapped; - private String msg; - - public VBoxException(Throwable wrapped, String msg) - { - this.wrapped = wrapped; - this.msg = msg; - } - public Throwable getWrapped() - { - return wrapped; - } - public String getMessage() - { - return msg; - } + public Holder() + { + } + public Holder(T value) + { + this.value = value; + } } ]]></xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'VBoxException.java'" /> - </xsl:call-template> - - + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'Holder.java'" /> + </xsl:call-template> </xsl:template> <xsl:template name="emitHandwrittenXpcom"> -<xsl:call-template name="startFile"> + <xsl:call-template name="startFile"> <xsl:with-param name="file" select="'IUnknown.java'" /> <xsl:with-param name="package" select="$G_virtualBoxPackageCom" /> </xsl:call-template> - <xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ public class IUnknown { - private Object obj; - public IUnknown(Object obj) - { - this.obj = obj; - } - - public Object getWrapped() - { - return this.obj; - } - - public void setWrapped(Object obj) - { - this.obj = obj; - } + private Object obj; + public IUnknown(Object obj) + { + this.obj = obj; + } + + public Object getWrapped() + { + return this.obj; + } + + public void setWrapped(Object obj) + { + this.obj = obj; + } } ]]></xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'IUnknown.java'" /> - </xsl:call-template> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'IUnknown.java'" /> + </xsl:call-template> - <xsl:call-template name="startFile"> - <xsl:with-param name="file" select="'Helper.java'" /> - <xsl:with-param name="package" select="$G_virtualBoxPackageCom" /> - </xsl:call-template> + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'Helper.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackageCom" /> + </xsl:call-template> -<xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ import java.util.List; import java.util.ArrayList; import java.util.Collections; import java.lang.reflect.Array; import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; -public class Helper { - public static List<Short> wrap(byte[] vals) { - if (vals==null) +public class Helper +{ + public static List<Short> wrap(byte[] values) + { + if (values == null) + return null; + + List<Short> ret = new ArrayList<Short>(values.length); + for (short v : values) + { + ret.add(v); + } + return ret; + } + + public static List<Short> wrap(short[] values) + { + if (values == null) return null; - List<Short> ret = new ArrayList<Short>(vals.length); - for (short v : vals) { - ret.add(v); + List<Short> ret = new ArrayList<Short>(values.length); + for (short v : values) + { + ret.add(v); } return ret; } - public static List<Integer> wrap(int[] vals) { - if (vals==null) - return null; + public static List<Integer> wrap(int[] values) + { + if (values == null) + return null; - List<Integer> ret = new ArrayList<Integer>(vals.length); - for (int v : vals) { - ret.add(v); + List<Integer> ret = new ArrayList<Integer>(values.length); + for (int v : values) + { + ret.add(v); } return ret; } - public static List<Long> wrap(long[] vals) { - if (vals==null) - return null; + public static List<Long> wrap(long[] values) + { + if (values == null) + return null; - List<Long> ret = new ArrayList<Long>(vals.length); - for (long v : vals) { - ret.add(v); + List<Long> ret = new ArrayList<Long>(values.length); + for (long v : values) + { + ret.add(v); } return ret; } - public static List<String> wrap(String[] vals) { - if (vals==null) + public static List<Boolean> wrap(boolean[] values) + { + if (values == null) return null; - List<String> ret = new ArrayList<String>(vals.length); - for (String v : vals) { + + List<Boolean> ret = new ArrayList<Boolean>(values.length); + for (boolean v: values) + { ret.add(v); } return ret; } - public static <T> List<T> wrap(Class<T> wrapperClass, T[] thisPtrs) { - if (thisPtrs==null) - return null; + public static List<String> wrap(String[] values) + { + if (values == null) + return null; - List<T> ret = new ArrayList<T>(thisPtrs.length); - for (T thisPtr : thisPtrs) { - ret.add(thisPtr); + List<String> ret = new ArrayList<String>(values.length); + for (String v : values) + { + ret.add(v); } return ret; } - public static <T> List<T> wrapEnum(Class<T> wrapperClass, long values[]) { - try { - if (values==null) - return null; - Constructor<T> c = wrapperClass.getConstructor(int.class); + public static <T> List<T> wrap(Class<T> wrapperClass, T[] values) + { + if (values == null) + return null; + + List<T> ret = new ArrayList<T>(values.length); + for (T v : values) + { + ret.add(v); + } + return ret; + } + + @SuppressWarnings( "unchecked") + public static <T> List<T> wrapEnum(Class<T> wrapperClass, long values[]) + { + try + { + if (values == null) + return null; + //// This code is questionable, as it invokes a private constructor + //// (all enums only have default constructors), and we don't really + //// know what to pass as the name, and the ordinal may or may not + //// be sensible, especially if the long was abused as a bitset. + //Constructor<T> c = wrapperClass.getDeclaredConstructor(String.class, int.class, int.class); + //c.setAccessible(true); // make it callable + //List<T> ret = new ArrayList<T>(values.length); + //for (long v : values) + //{ + // T convEnum = c.newInstance("unknown", (int)v, (int)v); + // ret.add(convEnum); + //} + + // Alternative implementation: use the fromValue method, which is + // what the code handling single enums will do. I see no reason to + // use the above very ugly hack if there are better alternatives, + // which as a bonus complain about unknown values. This variant is + // slower, but also orders of magnitude safer. + java.lang.reflect.Method fromValue = wrapperClass.getMethod("fromValue", long.class); List<T> ret = new ArrayList<T>(values.length); - for (long v : values) { - ret.add(c.newInstance(v)); + for (long v : values) + { + T convEnum = (T)fromValue.invoke(null, v); + ret.add(convEnum); } return ret; - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } catch (InstantiationException e) { + } + catch (NoSuchMethodException e) + { throw new AssertionError(e); - } catch (IllegalAccessException e) { + } + //catch (InstantiationException e) + //{ + // throw new AssertionError(e); + //} + catch (IllegalAccessException e) + { throw new AssertionError(e); - } catch (InvocationTargetException e) { + } + catch (InvocationTargetException e) + { throw new AssertionError(e); } } - public static short[] unwrapUShort(List<Short> vals) { - if (vals==null) - return null; + public static short[] unwrapUShort(List<Short> values) + { + if (values == null) + return null; - short[] ret = new short[vals.size()]; + short[] ret = new short[values.size()]; int i = 0; - for (short l : vals) { - ret[i++] = l; + for (short l : values) + { + ret[i++] = l; } return ret; } - public static int[] unwrapInteger(List<Integer> vals) { - if (vals == null) - return null; + public static int[] unwrapInteger(List<Integer> values) + { + if (values == null) + return null; - int[] ret = new int[vals.size()]; + int[] ret = new int[values.size()]; int i = 0; - for (int l : vals) { - ret[i++] = l; + for (int l : values) + { + ret[i++] = l; } return ret; } - public static long[] unwrapULong(List<Long> vals) { - if (vals == null) - return null; + public static long[] unwrapULong(List<Long> values) + { + if (values == null) + return null; - long[] ret = new long[vals.size()]; + long[] ret = new long[values.size()]; int i = 0; - for (long l : vals) { - ret[i++] = l; + for (long l : values) + { + ret[i++] = l; } return ret; } - public static boolean[] unwrapBoolean(List<Boolean> vals) { - if (vals==null) - return null; + public static boolean[] unwrapBoolean(List<Boolean> values) + { + if (values == null) + return null; - boolean[] ret = new boolean[vals.size()]; + boolean[] ret = new boolean[values.size()]; int i = 0; - for (boolean l : vals) { - ret[i++] = l; + for (boolean l : values) + { + ret[i++] = l; } return ret; } - public static String[] unwrapStr(List<String> vals) { - if (vals==null) + public static String[] unwrapStr(List<String> values) + { + if (values == null) return null; - String[] ret = new String[vals.size()]; + String[] ret = new String[values.size()]; int i = 0; - for (String l : vals) { - ret[i++] = l; + for (String l : values) + { + ret[i++] = l; } return ret; } - public static <T extends Enum <T>> long[] unwrapEnum(Class<T> enumClass, List<T> values) { - if (values == null) return null; + public static <T extends Enum <T>> long[] unwrapEnum(Class<T> enumClass, List<T> values) + { + if (values == null) + return null; long result[] = new long[values.size()]; - try { - java.lang.reflect.Method valueM = enumClass.getMethod("value"); - int i = 0; - for (T v : values) { - result[i++] = (Integer)valueM.invoke(v); - } - return result; - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } catch(SecurityException e) { - throw new AssertionError(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (IllegalArgumentException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - throw new AssertionError(e); + try + { + java.lang.reflect.Method valueM = enumClass.getMethod("value"); + int i = 0; + for (T v : values) + { + result[i++] = (Integer)valueM.invoke(v); + } + return result; + } + catch (NoSuchMethodException e) + { + throw new AssertionError(e); + } + catch(SecurityException e) + { + throw new AssertionError(e); + } + catch (IllegalAccessException e) + { + throw new AssertionError(e); + } + catch (IllegalArgumentException e) + { + throw new AssertionError(e); + } + catch (InvocationTargetException e) + { + throw new AssertionError(e); } } - public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, T2[] thisPtrs) { - try { - if (thisPtrs==null) + public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, T2[] values) + { + try + { + if (values == null) return null; Constructor<T1> c = wrapperClass1.getConstructor(wrapperClass2); - List<T1> ret = new ArrayList<T1>(thisPtrs.length); - for (T2 thisPtr : thisPtrs) { - ret.add(c.newInstance(thisPtr)); + List<T1> ret = new ArrayList<T1>(values.length); + for (T2 v : values) + { + ret.add(c.newInstance(v)); } return ret; - } catch (NoSuchMethodException e) { + } + catch (NoSuchMethodException e) + { throw new AssertionError(e); - } catch (InstantiationException e) { + } + catch (InstantiationException e) + { throw new AssertionError(e); - } catch (IllegalAccessException e) { + } + catch (IllegalAccessException e) + { throw new AssertionError(e); - } catch (InvocationTargetException e) { + } + catch (InvocationTargetException e) + { throw new AssertionError(e); } } @SuppressWarnings( "unchecked") - public static <T> T[] unwrap(Class<T> wrapperClass, List<T> thisPtrs) { - if (thisPtrs==null) + public static <T> T[] unwrap(Class<T> wrapperClass, List<T> values) + { + if (values == null) return null; - if (thisPtrs.size() == 0) + if (values.size() == 0) return null; - return (T[])thisPtrs.toArray((T[])Array.newInstance(wrapperClass, thisPtrs.size())); + return (T[])values.toArray((T[])Array.newInstance(wrapperClass, values.size())); } @SuppressWarnings( "unchecked" ) @@ -2794,40 +2975,112 @@ public class Helper { public static Object queryInterface(Object obj, String uuid) { - try { + try + { /* Kind of ugly, but does the job of casting */ org.mozilla.xpcom.Mozilla moz = org.mozilla.xpcom.Mozilla.getInstance(); long xpobj = moz.wrapJavaObject(obj, uuid); return moz.wrapXPCOMObject(xpobj, uuid); - } catch (Exception e) { - return null; - } + } + catch (Exception e) + { + return null; + } } @SuppressWarnings("unchecked") - public static <T1 extends IUnknown,T2> T2[] unwrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, List<T1> thisPtrs) { - if (thisPtrs==null) return null; + public static <T1 extends IUnknown, T2> T2[] unwrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, List<T1> values) + { + if (values == null) + return null; - T2 ret[] = (T2[])Array.newInstance(wrapperClass2, thisPtrs.size()); + T2 ret[] = (T2[])Array.newInstance(wrapperClass2, values.size()); int i = 0; - for (T1 obj : thisPtrs) { - ret[i++] = (T2)obj.getWrapped(); + for (T1 obj : values) + { + ret[i++] = (T2)obj.getWrapped(); } return ret; } } ]]></xsl:text> + </xsl:if> + + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'Helper.java'" /> + </xsl:call-template> + + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'VBoxException.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackage" /> + </xsl:call-template> + + <xsl:if test="$filelistonly=''"> + <xsl:text> +import org.mozilla.xpcom.*; + +public class VBoxException extends RuntimeException +{ + private int resultCode; + private IVirtualBoxErrorInfo errorInfo; + + public VBoxException(String message) + { + super(message); + resultCode = -1; + errorInfo = null; + } + + public VBoxException(String message, Throwable cause) + { + super(message, cause); + if (cause instanceof org.mozilla.xpcom.XPCOMException) + { + resultCode = (int)((org.mozilla.xpcom.XPCOMException)cause).errorcode; + try + { + Mozilla mozilla = Mozilla.getInstance(); + nsIServiceManager sm = mozilla.getServiceManager(); + nsIExceptionService es = (nsIExceptionService)sm.getServiceByContractID("@mozilla.org/exceptionservice;1", nsIExceptionService.NS_IEXCEPTIONSERVICE_IID); + nsIExceptionManager em = es.getCurrentExceptionManager(); + nsIException ex = em.getCurrentException(); + errorInfo = new IVirtualBoxErrorInfo((org.mozilla.interfaces.IVirtualBoxErrorInfo)ex.queryInterface(org.mozilla.interfaces.IVirtualBoxErrorInfo.IVIRTUALBOXERRORINFO_IID)); + } + catch (NullPointerException e) + { + e.printStackTrace(); + // nothing we can do + errorInfo = null; + } + } + else + resultCode = -1; + } + + public int getResultCode() + { + return resultCode; + } - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'Helper.java'" /> - </xsl:call-template> + public IVirtualBoxErrorInfo getVirtualBoxErrorInfo() + { + return errorInfo; + } +} +</xsl:text> + </xsl:if> - <xsl:call-template name="startFile"> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'VBoxException.java'" /> + </xsl:call-template> + + <xsl:call-template name="startFile"> <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> <xsl:with-param name="package" select="$G_virtualBoxPackage" /> </xsl:call-template> - <xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ import java.io.File; @@ -2836,8 +3089,8 @@ import org.mozilla.interfaces.*; public class VirtualBoxManager { - private Mozilla mozilla; - private IVirtualBox vbox; + private Mozilla mozilla; + private IVirtualBox vbox; private nsIComponentManager componentManager; private VirtualBoxManager(Mozilla mozilla) @@ -2852,12 +3105,12 @@ public class VirtualBoxManager public void connect(String url, String username, String passwd) { - throw new RuntimeException("Connect doesn't make sense for local bindings"); + throw new VBoxException("Connect doesn't make sense for local bindings"); } public void disconnect() { - throw new RuntimeException("Disconnect doesn't make sense for local bindings"); + throw new VBoxException("Disconnect doesn't make sense for local bindings"); } public static void initPerThread() @@ -2899,26 +3152,29 @@ public class VirtualBoxManager public static synchronized VirtualBoxManager createInstance(String home) { if (hasInstance) - throw new VBoxException(null, "only one instance at the time allowed"); - if (home == null || "".equals(home)) + throw new VBoxException("only one instance of VirtualBoxManager at a time allowed"); + if (home == null || home.equals("")) home = System.getProperty("vbox.home"); if (home == null) - throw new RuntimeException("vbox.home Java property must be defined to use XPCOM bridge"); + throw new VBoxException("vbox.home Java property must be defined to use XPCOM bridge"); File grePath = new File(home); Mozilla mozilla = Mozilla.getInstance(); if (!isMozillaInited) { - mozilla.initialize(grePath); - try { - mozilla.initXPCOM(grePath, null); - isMozillaInited = true; - } catch (Exception e) { - e.printStackTrace(); - return null; - } + mozilla.initialize(grePath); + try + { + mozilla.initXPCOM(grePath, null); + isMozillaInited = true; + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } } hasInstance = true; @@ -2928,8 +3184,9 @@ public class VirtualBoxManager public IEventListener createListener(Object sink) { - return new IEventListener(new EventListenerImpl(sink)); + return new IEventListener(new EventListenerImpl(sink)); } + public void cleanup() { deinitPerThread(); @@ -2940,141 +3197,127 @@ public class VirtualBoxManager hasInstance = false; } - public boolean progressBar(IProgress p, int wait) - { - long end = System.currentTimeMillis() + wait; - while (!p.getCompleted()) - { - mozilla.waitForEvents(0); - p.waitForCompletion(wait); - if (System.currentTimeMillis() >= end) - return false; - } - - return true; - } - - public boolean startVm(String name, String type, int timeout) - { - IMachine m = vbox.findMachine(name); - if (m == null) - return false; - ISession session = getSessionObject(); - - if (type == null) - type = "gui"; - IProgress p = m.launchVMProcess(session, type, ""); - progressBar(p, timeout); - session.unlockMachine(); - return true; - } - public void waitForEvents(long tmo) { mozilla.waitForEvents(tmo); } } ]]></xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> - </xsl:call-template> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> + </xsl:call-template> - <xsl:call-template name="startFile"> - <xsl:with-param name="file" select="'EventListenerImpl.java'" /> - <xsl:with-param name="package" select="$G_virtualBoxPackage" /> - </xsl:call-template> + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'EventListenerImpl.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackage" /> + </xsl:call-template> - <xsl:text><![CDATA[ - import org.mozilla.interfaces.*; + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ +import org.mozilla.interfaces.*; - public class EventListenerImpl extends nsISupportsBase implements org.mozilla.interfaces.IEventListener - { +public class EventListenerImpl extends nsISupportsBase implements org.mozilla.interfaces.IEventListener +{ private Object obj; private java.lang.reflect.Method handleEvent; EventListenerImpl(Object obj) { - this.obj = obj; - try { - this.handleEvent = obj.getClass().getMethod("handleEvent", IEvent.class); - } catch (Exception e) { - e.printStackTrace(); + this.obj = obj; + try + { + this.handleEvent = obj.getClass().getMethod("handleEvent", IEvent.class); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + public void handleEvent(org.mozilla.interfaces.IEvent ev) + { + try + { + if (obj != null && handleEvent != null) + handleEvent.invoke(obj, ev != null ? new IEvent(ev) : null); + } + catch (Exception e) + { + e.printStackTrace(); } - } - public void handleEvent(org.mozilla.interfaces.IEvent ev) - { - try { - if (obj != null && handleEvent != null) - handleEvent.invoke(obj, ev != null ? new IEvent(ev) : null); - } catch (Exception e) { - e.printStackTrace(); - } - } - }]]></xsl:text> - - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'EventListenerImpl.java'" /> - </xsl:call-template> - - <xsl:call-template name="startFile"> - <xsl:with-param name="file" select="'VBoxObjectBase.java'" /> - <xsl:with-param name="package" select="$G_virtualBoxPackage" /> - </xsl:call-template> - -<xsl:text><![CDATA[ + } +}]]></xsl:text> + </xsl:if> + + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'EventListenerImpl.java'" /> + </xsl:call-template> + + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'VBoxObjectBase.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackage" /> + </xsl:call-template> + + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ abstract class nsISupportsBase implements org.mozilla.interfaces.nsISupports { - public org.mozilla.interfaces.nsISupports queryInterface(String iid) + public org.mozilla.interfaces.nsISupports queryInterface(String iid) { return org.mozilla.xpcom.Mozilla.queryInterface(this, iid); } } -]]></xsl:text><xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'VBoxObjectBase.java'" /> - </xsl:call-template> +]]></xsl:text> + </xsl:if> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'VBoxObjectBase.java'" /> + </xsl:call-template> </xsl:template> <xsl:template name="emitHandwrittenMscom"> -<xsl:call-template name="startFile"> + <xsl:call-template name="startFile"> <xsl:with-param name="file" select="'IUnknown.java'" /> <xsl:with-param name="package" select="$G_virtualBoxPackageCom" /> </xsl:call-template> - <xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ public class IUnknown { - private Object obj; - public IUnknown(Object obj) - { - this.obj = obj; - } - - public Object getWrapped() - { - return this.obj; - } - - public void setWrapped(Object obj) - { - this.obj = obj; - } + private Object obj; + public IUnknown(Object obj) + { + this.obj = obj; + } + + public Object getWrapped() + { + return this.obj; + } + + public void setWrapped(Object obj) + { + this.obj = obj; + } } ]]></xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'IUnknown.java'" /> - </xsl:call-template> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'IUnknown.java'" /> + </xsl:call-template> -<xsl:call-template name="startFile"> - <xsl:with-param name="file" select="'Helper.java'" /> - <xsl:with-param name="package" select="$G_virtualBoxPackageCom" /> - </xsl:call-template> + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'Helper.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackageCom" /> + </xsl:call-template> -<xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ import java.util.List; import java.util.ArrayList; @@ -3084,101 +3327,129 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import com.jacob.com.*; -public class Helper { - public static List<Short> wrap(short[] vals) { - if (vals==null) return null; - if (vals.length == 0) return Collections.emptyList(); +public class Helper +{ + public static List<Short> wrap(short[] values) + { + if (values == null) + return null; + if (values.length == 0) + return Collections.emptyList(); - List<Short> ret = new ArrayList<Short>(vals.length); - for (short v : vals) { - ret.add(v); + List<Short> ret = new ArrayList<Short>(values.length); + for (short v : values) + { + ret.add(v); } return ret; } - public static List<Integer> wrap(int[] vals) { - if (vals == null) return null; - if (vals.length == 0) return Collections.emptyList(); + public static List<Integer> wrap(int[] values) + { + if (values == null) + return null; + if (values.length == 0) + return Collections.emptyList(); - List<Integer> ret = new ArrayList<Integer>(vals.length); - for (int v : vals) { - ret.add(v); + List<Integer> ret = new ArrayList<Integer>(values.length); + for (int v : values) + { + ret.add(v); } return ret; } - public static List<Long> wrap(long[] vals) { - if (vals==null) return null; - if (vals.length == 0) return Collections.emptyList(); + public static List<Long> wrap(long[] values) + { + if (values == null) + return null; + if (values.length == 0) + return Collections.emptyList(); - List<Long> ret = new ArrayList<Long>(vals.length); - for (long v : vals) { - ret.add(v); + List<Long> ret = new ArrayList<Long>(values.length); + for (long v : values) + { + ret.add(v); } return ret; } - public static List<String> wrap(String[] vals) { - if (vals==null) return null; - if (vals.length == 0) return Collections.emptyList(); + public static List<String> wrap(String[] values) + { + if (values == null) + return null; + if (values.length == 0) + return Collections.emptyList(); - List<String> ret = new ArrayList<String>(vals.length); - for (String v : vals) { - ret.add(v); + List<String> ret = new ArrayList<String>(values.length); + for (String v : values) + { + ret.add(v); } return ret; } public static <T> T wrapDispatch(Class<T> wrapperClass, Dispatch d) { - try { - if (d == null || d.m_pDispatch == 0) - return null; - Constructor<T> c = wrapperClass.getConstructor(Dispatch.class); - return (T)c.newInstance(d); - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } catch (InstantiationException e) { - throw new AssertionError(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - throw new AssertionError(e); - } + try + { + if (d == null || d.m_pDispatch == 0) + return null; + Constructor<T> c = wrapperClass.getConstructor(Dispatch.class); + return (T)c.newInstance(d); + } + catch (NoSuchMethodException e) + { + throw new AssertionError(e); + } + catch (InstantiationException e) + { + throw new AssertionError(e); + } + catch (IllegalAccessException e) + { + throw new AssertionError(e); + } + catch (InvocationTargetException e) + { + throw new AssertionError(e); + } } @SuppressWarnings("unchecked") public static <T> Object wrapVariant(Class<T> wrapperClass, Variant v) { - if (v == null) - return null; - - short vt = v.getvt(); - switch (vt) - { - case Variant.VariantNull: - return null; - case Variant.VariantBoolean: - return v.getBoolean(); - case Variant.VariantByte: - return v.getByte(); - case Variant.VariantShort: - return v.getShort(); - case Variant.VariantInt: - return v.getInt(); - case Variant.VariantLongInt: - return v.getLong(); - case Variant.VariantString: - return v.getString(); - case Variant.VariantDispatch: - return wrapDispatch(wrapperClass, v.getDispatch()); - default: - throw new RuntimeException("unhandled variant type "+vt); - } + if (v == null) + return null; + + short vt = v.getvt(); + switch (vt) + { + case Variant.VariantNull: + return null; + case Variant.VariantBoolean: + return v.getBoolean(); + case Variant.VariantByte: + return v.getByte(); + case Variant.VariantShort: + return v.getShort(); + case Variant.VariantInt: + return v.getInt(); + case Variant.VariantLongInt: + return v.getLong(); + case Variant.VariantString: + return v.getString(); + case Variant.VariantDispatch: + return wrapDispatch(wrapperClass, v.getDispatch()); + default: + throw new VBoxException("unhandled variant type " + vt); + } } - public static byte[] wrapBytes(SafeArray sa) { - if (sa==null) return null; + public static byte[] wrapBytes(SafeArray sa) + { + if (sa == null) + return null; int saLen = sa.getUBound() - sa.getLBound() + 1; @@ -3186,168 +3457,229 @@ public class Helper { int j = 0; for (int i = sa.getLBound(); i <= sa.getUBound(); i++) { - Variant v = sa.getVariant(i); - // come upo with more effective approach!!! - ret[j++] = v.getByte(); + Variant v = sa.getVariant(i); + // come up with more effective approach!!! + ret[j++] = v.getByte(); } return ret; } @SuppressWarnings("unchecked") - public static <T> List<T> wrap(Class<T> wrapperClass, SafeArray sa) { - if (sa==null) return null; + public static <T> List<T> wrap(Class<T> wrapperClass, SafeArray sa) + { + if (sa == null) + return null; int saLen = sa.getUBound() - sa.getLBound() + 1; - if (saLen == 0) return Collections.emptyList(); + if (saLen == 0) + return Collections.emptyList(); List<T> ret = new ArrayList<T>(saLen); for (int i = sa.getLBound(); i <= sa.getUBound(); i++) { - Variant v = sa.getVariant(i); - ret.add((T)wrapVariant(wrapperClass, v)); + Variant v = sa.getVariant(i); + ret.add((T)wrapVariant(wrapperClass, v)); } return ret; } - public static <T> List<T> wrapEnum(Class<T> wrapperClass, SafeArray sa) { - try { - if (sa==null) return null; - - int saLen = sa.getUBound() - sa.getLBound() + 1; - if (saLen == 0) return Collections.emptyList(); - List<T> ret = new ArrayList<T>(saLen); - Constructor<T> c = wrapperClass.getConstructor(int.class); - for (int i = sa.getLBound(); i <= sa.getUBound(); i++) - { - Variant v = sa.getVariant(i); - ret.add(c.newInstance(v.getInt())); - } - return ret; - } catch (NoSuchMethodException e) { + public static <T> List<T> wrapEnum(Class<T> wrapperClass, SafeArray sa) + { + try + { + if (sa == null) + return null; + + int saLen = sa.getUBound() - sa.getLBound() + 1; + if (saLen == 0) + return Collections.emptyList(); + List<T> ret = new ArrayList<T>(saLen); + Constructor<T> c = wrapperClass.getConstructor(int.class); + for (int i = sa.getLBound(); i <= sa.getUBound(); i++) + { + Variant v = sa.getVariant(i); + ret.add(c.newInstance(v.getInt())); + } + return ret; + } + catch (NoSuchMethodException e) + { throw new AssertionError(e); - } catch (InstantiationException e) { + } + catch (InstantiationException e) + { throw new AssertionError(e); - } catch (IllegalAccessException e) { + } + catch (IllegalAccessException e) + { throw new AssertionError(e); - } catch (InvocationTargetException e) { + } + catch (InvocationTargetException e) + { throw new AssertionError(e); } } - public static SafeArray unwrapInt(List<Integer> vals) { - if (vals==null) return null; - SafeArray ret = new SafeArray(Variant.VariantInt, vals.size()); + public static SafeArray unwrapInt(List<Integer> values) + { + if (values == null) + return null; + SafeArray ret = new SafeArray(Variant.VariantInt, values.size()); int i = 0; - for (int l : vals) { - ret.setInt(i++, l); + for (int l : values) + { + ret.setInt(i++, l); } return ret; } - public static SafeArray unwrapLong(List<Long> vals) { - if (vals==null) return null; - SafeArray ret = new SafeArray(Variant.VariantLongInt, vals.size()); + public static SafeArray unwrapLong(List<Long> values) + { + if (values == null) + return null; + SafeArray ret = new SafeArray(Variant.VariantLongInt, values.size()); int i = 0; - for (long l : vals) { - ret.setLong(i++, l); + for (long l : values) + { + ret.setLong(i++, l); } return ret; } - public static SafeArray unwrapBool(List<Boolean> vals) { - if (vals==null) return null; + public static SafeArray unwrapBool(List<Boolean> values) + { + if (values == null) + return null; - SafeArray result = new SafeArray(Variant.VariantBoolean, vals.size()); + SafeArray result = new SafeArray(Variant.VariantBoolean, values.size()); int i = 0; - for (boolean l : vals) { - result.setBoolean(i++, l); + for (boolean l : values) + { + result.setBoolean(i++, l); } return result; } - public static SafeArray unwrapBytes(byte[] vals) { - if (vals==null) return null; + public static SafeArray unwrapBytes(byte[] values) + { + if (values == null) + return null; - SafeArray result = new SafeArray(Variant.VariantByte, vals.length); + SafeArray result = new SafeArray(Variant.VariantByte, values.length); int i = 0; - for (byte l : vals) { - result.setByte(i++, l); + for (byte l : values) + { + result.setByte(i++, l); } return result; } - public static <T extends Enum <T>> SafeArray unwrapEnum(Class<T> enumClass, List<T> values) { - if (values == null) return null; + public static <T extends Enum <T>> SafeArray unwrapEnum(Class<T> enumClass, List<T> values) + { + if (values == null) + return null; SafeArray result = new SafeArray(Variant.VariantInt, values.size()); - try { - java.lang.reflect.Method valueM = enumClass.getMethod("value"); - int i = 0; - for (T v : values) { - result.setInt(i++, (Integer)valueM.invoke(v)); - } - return result; - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } catch(SecurityException e) { - throw new AssertionError(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (IllegalArgumentException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - throw new AssertionError(e); + try + { + java.lang.reflect.Method valueM = enumClass.getMethod("value"); + int i = 0; + for (T v : values) + { + result.setInt(i++, (Integer)valueM.invoke(v)); + } + return result; + } + catch (NoSuchMethodException e) + { + throw new AssertionError(e); + } + catch(SecurityException e) + { + throw new AssertionError(e); + } + catch (IllegalAccessException e) + { + throw new AssertionError(e); + } + catch (IllegalArgumentException e) + { + throw new AssertionError(e); + } + catch (InvocationTargetException e) + { + throw new AssertionError(e); } } - public static SafeArray unwrapString(List<String> vals) { - if (vals==null) - return null; - SafeArray result = new SafeArray(Variant.VariantString, vals.size()); + public static SafeArray unwrapString(List<String> values) + { + if (values == null) + return null; + SafeArray result = new SafeArray(Variant.VariantString, values.size()); int i = 0; - for (String l : vals) { - result.setString(i++, l); + for (String l : values) + { + result.setString(i++, l); } return result; } - public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, T2[] thisPtrs) { - try { - if (thisPtrs==null) return null; - if (thisPtrs.length == 0) return Collections.emptyList(); + public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, T2[] values) + { + try + { + if (values == null) + return null; + if (values.length == 0) + return Collections.emptyList(); Constructor<T1> c = wrapperClass1.getConstructor(wrapperClass2); - List<T1> ret = new ArrayList<T1>(thisPtrs.length); - for (T2 thisPtr : thisPtrs) { - ret.add(c.newInstance(thisPtr)); + List<T1> ret = new ArrayList<T1>(values.length); + for (T2 v : values) + { + ret.add(c.newInstance(v)); } return ret; - } catch (NoSuchMethodException e) { + } + catch (NoSuchMethodException e) + { throw new AssertionError(e); - } catch (InstantiationException e) { + } + catch (InstantiationException e) + { throw new AssertionError(e); - } catch (IllegalAccessException e) { + } + catch (IllegalAccessException e) + { throw new AssertionError(e); - } catch (InvocationTargetException e) { + } + catch (InvocationTargetException e) + { throw new AssertionError(e); } } @SuppressWarnings("unchecked") - public static <T> T[] unwrap(Class<T> wrapperClass, List<T> thisPtrs) { - if (thisPtrs==null) return null; - return (T[])thisPtrs.toArray((T[])Array.newInstance(wrapperClass, thisPtrs.size())); + public static <T> T[] unwrap(Class<T> wrapperClass, List<T> values) + { + if (values == null) + return null; + return (T[])values.toArray((T[])Array.newInstance(wrapperClass, values.size())); } @SuppressWarnings("unchecked") - public static <T1 extends IUnknown,T2> T2[] unwrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, List<T1> thisPtrs) { - if (thisPtrs==null) return null; + public static <T1 extends IUnknown, T2> T2[] unwrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, List<T1> values) + { + if (values == null) + return null; - T2 ret[] = (T2[])Array.newInstance(wrapperClass2, thisPtrs.size()); + T2 ret[] = (T2[])Array.newInstance(wrapperClass2, values.size()); int i = 0; - for (T1 obj : thisPtrs) { - ret[i++] = (T2)obj.getWrapped(); + for (T1 obj : values) + { + ret[i++] = (T2)obj.getWrapped(); } return ret; } @@ -3359,18 +3691,72 @@ public class Helper { } } ]]></xsl:text> + </xsl:if> + + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'Helper.java'" /> + </xsl:call-template> + + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'VBoxException.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackage" /> + </xsl:call-template> + + <xsl:if test="$filelistonly=''"> + <xsl:text> + +public class VBoxException extends RuntimeException +{ + private int resultCode; + private IVirtualBoxErrorInfo errorInfo; + + public VBoxException(String message) + { + super(message); + resultCode = -1; + errorInfo = null; + } + + public VBoxException(String message, Throwable cause) + { + super(message, cause); + if (cause instanceof com.jacob.com.ComException) + { + resultCode = ((com.jacob.com.ComException)cause).getHResult(); + // JACOB doesn't support calling GetErrorInfo, which + // means there is no way of getting an IErrorInfo reference, + // and that means no way of getting to IVirtualBoxErrorInfo. + errorInfo = null; + } + else + resultCode = -1; + } + + public int getResultCode() + { + return resultCode; + } + + public IVirtualBoxErrorInfo getVirtualBoxErrorInfo() + { + return errorInfo; + } +} +</xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'Helper.java'" /> - </xsl:call-template> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'VBoxException.java'" /> + </xsl:call-template> - <xsl:call-template name="startFile"> + <xsl:call-template name="startFile"> <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> <xsl:with-param name="package" select="$G_virtualBoxPackage" /> </xsl:call-template> - <xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComThread; @@ -3381,7 +3767,7 @@ import com.jacob.com.DispatchEvents; public class VirtualBoxManager { - private IVirtualBox vbox; + private IVirtualBox vbox; private VirtualBoxManager() { @@ -3391,22 +3777,22 @@ public class VirtualBoxManager public static void initPerThread() { - ComThread.InitMTA(); + ComThread.InitMTA(); } public static void deinitPerThread() { - ComThread.Release(); + ComThread.Release(); } public void connect(String url, String username, String passwd) { - throw new RuntimeException("Connect doesn't make sense for local bindings"); + throw new VBoxException("Connect doesn't make sense for local bindings"); } public void disconnect() { - throw new RuntimeException("Disconnect doesn't make sense for local bindings"); + throw new VBoxException("Disconnect doesn't make sense for local bindings"); } public IVirtualBox getVBox() @@ -3437,7 +3823,7 @@ public class VirtualBoxManager public static synchronized VirtualBoxManager createInstance(String home) { if (hasInstance) - throw new VBoxException(null, "only one instance at the time allowed"); + throw new VBoxException("only one instance of VirtualBoxManager at a time allowed"); hasInstance = true; return new VirtualBoxManager(); @@ -3449,48 +3835,24 @@ public class VirtualBoxManager hasInstance = false; } - public boolean progressBar(IProgress p, int wait) - { - long end = System.currentTimeMillis() + wait; - while (!p.getCompleted()) - { - p.waitForCompletion(wait); - if (System.currentTimeMillis() >= end) - return false; - } - - return true; - } - - public boolean startVm(String name, String type, int timeout) - { - IMachine m = vbox.findMachine(name); - if (m == null) - return false; - ISession session = getSessionObject(); - if (type == null) - type = "gui"; - IProgress p = m.launchVMProcess(session, type, ""); - progressBar(p, timeout); - session.unlockMachine(); - return true; - } - public void waitForEvents(long tmo) { // what to do here? - try { + try + { Thread.sleep(tmo); - } catch (InterruptedException ie) { + } + catch (InterruptedException ie) + { } } } ]]></xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> - </xsl:call-template> - + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> + </xsl:call-template> </xsl:template> <xsl:template name="emitHandwrittenJaxws"> @@ -3500,55 +3862,63 @@ public class VirtualBoxManager <xsl:with-param name="package" select="$G_virtualBoxPackage" /> </xsl:call-template> - <xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ public class IUnknown { - protected String obj; - protected final VboxPortType port; - - public IUnknown(String obj, VboxPortType port) - { - this.obj = obj; - this.port = port; - } - - public final String getWrapped() - { - return this.obj; - } - - public final VboxPortType getRemoteWSPort() - { - return this.port; - } - - public synchronized void releaseRemote() throws WebServiceException - { - if (obj == null) { - return; - } - try { - this.port.iManagedObjectRefRelease(obj); - this.obj = null; - } catch (InvalidObjectFaultMsg e) { - throw new WebServiceException(e); - } catch (RuntimeFaultMsg e) { - throw new WebServiceException(e); - } - } + protected String obj; + protected final VboxPortType port; + + public IUnknown(String obj, VboxPortType port) + { + this.obj = obj; + this.port = port; + } + + public final String getWrapped() + { + return this.obj; + } + + public final VboxPortType getRemoteWSPort() + { + return this.port; + } + + public synchronized void releaseRemote() throws WebServiceException + { + if (obj == null) + return; + + try + { + this.port.iManagedObjectRefRelease(obj); + this.obj = null; + } + catch (InvalidObjectFaultMsg e) + { + throw new WebServiceException(e); + } + catch (RuntimeFaultMsg e) + { + throw new WebServiceException(e); + } + } } ]]></xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'IUnknown.java'" /> - </xsl:call-template> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'IUnknown.java'" /> + </xsl:call-template> - <xsl:call-template name="startFile"> - <xsl:with-param name="file" select="'Helper.java'" /> - <xsl:with-param name="package" select="$G_virtualBoxPackage" /> - </xsl:call-template> + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'Helper.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackage" /> + </xsl:call-template> -<xsl:text><![CDATA[ + <xsl:if test="$filelistonly=''"> + <xsl:text><![CDATA[ import java.util.List; import java.util.ArrayList; @@ -3558,54 +3928,82 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigInteger; -public class Helper { - public static <T> List<T> wrap(Class<T> wrapperClass, VboxPortType pt, List<String> thisPtrs) { - try { - if(thisPtrs==null) return null; +public class Helper +{ + public static <T> List<T> wrap(Class<T> wrapperClass, VboxPortType pt, List<String> values) + { + try + { + if (values == null) + return null; Constructor<T> c = wrapperClass.getConstructor(String.class, VboxPortType.class); - List<T> ret = new ArrayList<T>(thisPtrs.size()); - for (String thisPtr : thisPtrs) { - ret.add(c.newInstance(thisPtr,pt)); + List<T> ret = new ArrayList<T>(values.size()); + for (String v : values) + { + ret.add(c.newInstance(v, pt)); } return ret; - } catch (NoSuchMethodException e) { + } + catch (NoSuchMethodException e) + { throw new AssertionError(e); - } catch (InstantiationException e) { + } + catch (InstantiationException e) + { throw new AssertionError(e); - } catch (IllegalAccessException e) { + } + catch (IllegalAccessException e) + { throw new AssertionError(e); - } catch (InvocationTargetException e) { + } + catch (InvocationTargetException e) + { throw new AssertionError(e); } } - public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, VboxPortType pt, List<T2> thisPtrs) { - try { - if(thisPtrs==null) return null; + public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, VboxPortType pt, List<T2> values) + { + try + { + if (values == null) + return null; Constructor<T1> c = wrapperClass1.getConstructor(wrapperClass2, VboxPortType.class); - List<T1> ret = new ArrayList<T1>(thisPtrs.size()); - for (T2 thisPtr : thisPtrs) { - ret.add(c.newInstance(thisPtr,pt)); + List<T1> ret = new ArrayList<T1>(values.size()); + for (T2 v : values) + { + ret.add(c.newInstance(v, pt)); } return ret; - } catch (NoSuchMethodException e) { + } + catch (NoSuchMethodException e) + { throw new AssertionError(e); - } catch (InstantiationException e) { + } + catch (InstantiationException e) + { throw new AssertionError(e); - } catch (IllegalAccessException e) { + } + catch (IllegalAccessException e) + { throw new AssertionError(e); - } catch (InvocationTargetException e) { + } + catch (InvocationTargetException e) + { throw new AssertionError(e); } } - public static <T extends IUnknown> List<String> unwrap(List<T> thisPtrs) { - if (thisPtrs==null) return null; + public static <T extends IUnknown> List<String> unwrap(List<T> values) + { + if (values == null) + return null; - List<String> ret = new ArrayList<String>(thisPtrs.size()); - for (T obj : thisPtrs) { + List<String> ret = new ArrayList<String>(values.size()); + for (T obj : values) + { ret.add(obj.getWrapped()); } return ret; @@ -3614,22 +4012,25 @@ public class Helper { @SuppressWarnings("unchecked" ) public static <T1 extends Enum <T1>, T2 extends Enum <T2>> List<T2> convertEnums(Class<T1> fromClass, Class<T2> toClass, - List<T1> values) { - try { - if (values==null) - return null; - java.lang.reflect.Method fromValue = toClass.getMethod("fromValue", String.class); + List<T1> values) + { + try + { + if (values == null) + return null; List<T2> ret = new ArrayList<T2>(values.size()); - for (T1 v : values) { - // static method is called with null this - ret.add((T2)fromValue.invoke(null, v.name())); + for (T1 v : values) + { + // Ordinal based enum conversion, as JAX-WS "invents" its own + // enum names and has string values with the expected content. + int enumOrdinal = v.ordinal(); + T2 convEnum = toClass.getEnumConstants()[enumOrdinal]; + ret.add(convEnum); } return ret; - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { + } + catch (ArrayIndexOutOfBoundsException e) + { throw new AssertionError(e); } } @@ -3645,7 +4046,7 @@ public class Helper { charToVal[i] = -1; for (int i = 0; i < valToChar.length; i++) - charToVal[valToChar[i]] = i; + charToVal[valToChar[i]] = i; charToVal['='] = 0; } @@ -3699,7 +4100,7 @@ public class Helper { break; } default: - throw new RuntimeException("bug!"); + throw new VBoxException("bug!"); } return new String(result); @@ -3735,7 +4136,7 @@ public class Helper { } if ((validChars * 3 % 4) != 0) - throw new RuntimeException("invalid encoded string "+str); + throw new VBoxException("invalid base64 encoded string " + str); int resultLength = validChars * 3 / 4 - padChars; byte[] result = new byte[resultLength]; @@ -3743,7 +4144,7 @@ public class Helper { int dataIndex = 0, stringIndex = 0; int quadraplets = validChars / 4; - for (int i=0; i<quadraplets; i++) + for (int i = 0; i < quadraplets; i++) { stringIndex = skipInvalid(str, stringIndex); int ch1 = str.charAt(stringIndex++); @@ -3766,17 +4167,77 @@ public class Helper { } } ]]></xsl:text> + </xsl:if> + + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'Helper.java'" /> + </xsl:call-template> + + <xsl:call-template name="startFile"> + <xsl:with-param name="file" select="'VBoxException.java'" /> + <xsl:with-param name="package" select="$G_virtualBoxPackage" /> + </xsl:call-template> + + <xsl:if test="$filelistonly=''"> + <xsl:text> +public class VBoxException extends RuntimeException +{ + private int resultCode; + private IVirtualBoxErrorInfo errorInfo; + + public VBoxException(String message) + { + super(message); + resultCode = -1; + errorInfo = null; + } + + public VBoxException(String message, Throwable cause) + { + super(message, cause); + resultCode = -1; + errorInfo = null; + } + + public VBoxException(String message, Throwable cause, VboxPortType port) + { + super(message, cause); + if (cause instanceof RuntimeFaultMsg) + { + RuntimeFaultMsg m = (RuntimeFaultMsg)cause; + RuntimeFault f = m.getFaultInfo(); + resultCode = f.getResultCode(); + String retVal = f.getReturnval(); + errorInfo = (retVal.length() > 0) ? new IVirtualBoxErrorInfo(retVal, port) : null; + } + else + resultCode = -1; + } + + public int getResultCode() + { + return resultCode; + } + + public IVirtualBoxErrorInfo getVirtualBoxErrorInfo() + { + return errorInfo; + } +} +</xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'Helper.java'" /> - </xsl:call-template> + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'VBoxException.java'" /> + </xsl:call-template> - <xsl:call-template name="startFile"> + <xsl:call-template name="startFile"> <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> <xsl:with-param name="package" select="$G_virtualBoxPackage" /> - </xsl:call-template> + </xsl:call-template> -import java.net.URL; + <xsl:if test="$filelistonly=''"> + <xsl:text>import java.net.URL; import java.math.BigInteger; import java.util.List; import java.util.Map; @@ -3788,10 +4249,10 @@ import javax.xml.ws.WebServiceException; class PortPool { - private final static String wsdlFile = <xsl:value-of select="$G_virtualBoxWsdl" />; - - <xsl:text><![CDATA[ -private Map<VboxPortType, Integer> known; + private final static String wsdlFile = </xsl:text> + <xsl:value-of select="$G_virtualBoxWsdl" /> + <xsl:text><![CDATA[; + private Map<VboxPortType, Integer> known; private boolean initStarted; private VboxService svc; @@ -3801,32 +4262,35 @@ private Map<VboxPortType, Integer> known; if (usePreinit) { - new Thread(new Runnable() - { - public void run() - { - // need to sync on something else but 'this' - synchronized (known) + new Thread(new Runnable() + { + public void run() { - initStarted = true; - known.notify(); + // need to sync on something else but 'this' + synchronized (known) + { + initStarted = true; + known.notify(); + } + + preinit(); } + }).start(); - preinit(); - } - }).start(); - - synchronized (known) - { - while (!initStarted) - { - try { - known.wait(); - } catch (InterruptedException e) { - break; - } - } - } + synchronized (known) + { + while (!initStarted) + { + try + { + known.wait(); + } + catch (InterruptedException e) + { + break; + } + } + } } } @@ -3854,10 +4318,11 @@ private Map<VboxPortType, Integer> known; if (port == null) { - if (svc == null) { + if (svc == null) + { URL wsdl = PortPool.class.getClassLoader().getResource(wsdlFile); if (wsdl == null) - throw new LinkageError(wsdlFile+" not found, but it should have been in the jar"); + throw new LinkageError(wsdlFile + " not found, but it should have been in the jar"); svc = new VboxService(wsdl, new QName("http://www.virtualbox.org/Service", "vboxService")); @@ -3901,7 +4366,7 @@ public class VirtualBoxManager private static PortPool pool = new PortPool(true); protected VboxPortType port; - private IVirtualBox vbox; + private IVirtualBox vbox; private VirtualBoxManager() { @@ -3918,18 +4383,22 @@ public class VirtualBoxManager public void connect(String url, String username, String passwd) { this.port = pool.getPort(); - try { + try + { ((BindingProvider)port).getRequestContext(). put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url); String handle = port.iWebsessionManagerLogon(username, passwd); this.vbox = new IVirtualBox(handle, port); - } catch (Throwable t) { - if (this.port != null && pool != null) { + } + catch (Throwable t) + { + if (this.port != null && pool != null) + { pool.releasePort(this.port); this.port = null; } // we have to throw smth derived from RuntimeException - throw new VBoxException(t, t.getMessage()); + throw new VBoxException(t.getMessage(), t, this.port); } } @@ -3938,7 +4407,8 @@ public class VirtualBoxManager { this.port = pool.getPort(); - try { + try + { ((BindingProvider)port).getRequestContext(); if (requestContext != null) ((BindingProvider)port).getRequestContext().putAll(requestContext); @@ -3950,27 +4420,41 @@ public class VirtualBoxManager put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url); String handle = port.iWebsessionManagerLogon(username, passwd); this.vbox = new IVirtualBox(handle, port); - } catch (Throwable t) { - if (this.port != null && pool != null) { + } + catch (Throwable t) + { + if (this.port != null && pool != null) + { pool.releasePort(this.port); this.port = null; } // we have to throw smth derived from RuntimeException - throw new VBoxException(t, t.getMessage()); + throw new VBoxException(t.getMessage(), t, this.port); } } public void disconnect() { - try { - if (this.vbox != null) - port.iWebsessionManagerLogoff(this.vbox.getWrapped()); - } catch (InvalidObjectFaultMsg e) { - throw new VBoxException(e, e.getMessage()); - } catch (RuntimeFaultMsg e) { - throw new VBoxException(e, e.getMessage()); - } finally { - if (this.port != null) { + if (this.port == null) + return; + + try + { + if (this.vbox != null && port != null) + port.iWebsessionManagerLogoff(this.vbox.getWrapped()); + } + catch (InvalidObjectFaultMsg e) + { + throw new VBoxException(e.getMessage(), e, this.port); + } + catch (RuntimeFaultMsg e) + { + throw new VBoxException(e.getMessage(), e, this.port); + } + finally + { + if (this.port != null) + { pool.releasePort(this.port); this.port = null; } @@ -3985,14 +4469,19 @@ public class VirtualBoxManager public ISession getSessionObject() { if (this.vbox == null) - throw new RuntimeException("connect first"); - try { - String handle = port.iWebsessionManagerGetSessionObject(this.vbox.getWrapped()); - return new ISession(handle, port); - } catch (InvalidObjectFaultMsg e) { - throw new VBoxException(e, e.getMessage()); - } catch (RuntimeFaultMsg e) { - throw new VBoxException(e, e.getMessage()); + throw new VBoxException("connect first"); + try + { + String handle = port.iWebsessionManagerGetSessionObject(this.vbox.getWrapped()); + return new ISession(handle, port); + } + catch (InvalidObjectFaultMsg e) + { + throw new VBoxException(e.getMessage(), e, this.port); + } + catch (RuntimeFaultMsg e) + { + throw new VBoxException(e.getMessage(), e, this.port); } } @@ -4016,63 +4505,40 @@ public class VirtualBoxManager public IEventListener createListener(Object sink) { - throw new RuntimeException("no active listeners here"); + throw new VBoxException("no active listeners here"); } + public void cleanup() { disconnect(); deinitPerThread(); } - public boolean progressBar(IProgress p, int wait) - { - long end = System.currentTimeMillis() + wait; - while (!p.getCompleted()) - { - p.waitForCompletion(wait); - if (System.currentTimeMillis() >= end) - return false; - } - - return true; - } - - public boolean startVm(String name, String type, int timeout) - { - IMachine m = vbox.findMachine(name); - if (m == null) - return false; - ISession session = getSessionObject(); - - if (type == null) - type = "gui"; - IProgress p = m.launchVMProcess(session, type, ""); - progressBar(p, timeout); - session.unlockMachine(); - return true; - } - public void waitForEvents(long tmo) { } - - protected void finalize() throws Throwable + + protected void finalize() throws Throwable { - try { + try + { cleanup(); - } catch(Exception e) { } - finally { + catch(Exception e) + { + } + finally + { super.finalize(); } } } ]]></xsl:text> + </xsl:if> - <xsl:call-template name="endFile"> - <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> - </xsl:call-template> - + <xsl:call-template name="endFile"> + <xsl:with-param name="file" select="'VirtualBoxManager.java'" /> + </xsl:call-template> </xsl:template> @@ -4084,6 +4550,10 @@ public class VirtualBoxManager </xsl:call-template> </xsl:if> + <xsl:if test="not($filelistonly='')"> + <xsl:value-of select="concat($filelistonly, ' := \ ')"/> + </xsl:if> + <!-- Handwritten files --> <xsl:call-template name="emitHandwritten"/> @@ -4122,7 +4592,7 @@ public class VirtualBoxManager <xsl:choose> <xsl:when test="$G_vboxGlueStyle='jaxws'"> - <xsl:if test="not($module) and not(@wsmap='suppress') and not(@wsmap='global')"> + <xsl:if test="not($module) and not(@wsmap='suppress')"> <xsl:call-template name="genIface"> <xsl:with-param name="ifname" select="@name" /> <xsl:with-param name="filename" select="concat(@name, '.java')" /> @@ -4142,5 +4612,10 @@ public class VirtualBoxManager </xsl:choose> </xsl:for-each> + + <xsl:if test="not($filelistonly='')"> + <xsl:value-of select="' '"/> + </xsl:if> + </xsl:template> </xsl:stylesheet> diff --git a/src/VBox/Main/glue/initterm.cpp b/src/VBox/Main/glue/initterm.cpp index 6e9e1c6e..dbc493c8 100644 --- a/src/VBox/Main/glue/initterm.cpp +++ b/src/VBox/Main/glue/initterm.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -20,20 +20,10 @@ # include <objbase.h> -#else /* !defined (VBOX_WITH_XPCOM) */ +#else /* !defined(VBOX_WITH_XPCOM) */ # include <stdlib.h> - /* XPCOM_GLUE is defined when the client uses the standalone glue - * (i.e. dynamically picks up the existing XPCOM shared library installation). - * This is not the case for VirtualBox XPCOM clients (they are always - * distributed with the self-built XPCOM library, and therefore have a binary - * dependency on it) but left here for clarity. - */ -# if defined(XPCOM_GLUE) -# include <nsXPCOMGlue.h> -# endif - # include <nsIComponentRegistrar.h> # include <nsIServiceManager.h> # include <nsCOMPtr.h> @@ -48,7 +38,7 @@ #include "VBox/com/com.h" #include "VBox/com/assert.h" -#include "VBox/com/EventQueue.h" +#include "VBox/com/NativeEventQueue.h" #include "VBox/com/AutoLock.h" #include "../include/Logging.h" @@ -182,7 +172,7 @@ DirectoryServiceProvider::GetFile(const char *aProp, if (NS_FAILED(rv)) return rv; - return localFile->QueryInterface(NS_GET_IID (nsIFile), (void **)aRetval); + return localFile->QueryInterface(NS_GET_IID(nsIFile), (void **)aRetval); } /** @@ -196,7 +186,7 @@ static bool volatile gIsXPCOMInitialized = false; */ static unsigned int gXPCOMInitCount = 0; -#else /* !defined (VBOX_WITH_XPCOM) */ +#else /* !defined(VBOX_WITH_XPCOM) */ /** * The COM main thread handle. (The first caller of com::Initialize().) @@ -208,7 +198,7 @@ static RTTHREAD volatile gCOMMainThread = NIL_RTTHREAD; */ static uint32_t gCOMMainInitCount = 0; -#endif /* !defined (VBOX_WITH_XPCOM) */ +#endif /* !defined(VBOX_WITH_XPCOM) */ /** @@ -304,7 +294,7 @@ HRESULT Initialize(bool fGui) if (SUCCEEDED(rc)) gCOMMainInitCount = 1; -#else /* !defined (VBOX_WITH_XPCOM) */ +#else /* !defined(VBOX_WITH_XPCOM) */ /* Unused here */ NOREF(fGui); @@ -345,33 +335,34 @@ HRESULT Initialize(bool fGui) if (vrc == VERR_ACCESS_DENIED) return NS_ERROR_FILE_ACCESS_DENIED; AssertRCReturn(vrc, NS_ERROR_FAILURE); - strcpy(szXptiDat, szCompReg); - + vrc = RTStrCopy(szXptiDat, sizeof(szXptiDat), szCompReg); + AssertRCReturn(vrc, NS_ERROR_FAILURE); +#ifdef VBOX_IN_32_ON_64_MAIN_API + vrc = RTPathAppend(szCompReg, sizeof(szCompReg), "compreg-x86.dat"); + AssertRCReturn(vrc, NS_ERROR_FAILURE); + vrc = RTPathAppend(szXptiDat, sizeof(szXptiDat), "xpti-x86.dat"); + AssertRCReturn(vrc, NS_ERROR_FAILURE); +#else vrc = RTPathAppend(szCompReg, sizeof(szCompReg), "compreg.dat"); AssertRCReturn(vrc, NS_ERROR_FAILURE); vrc = RTPathAppend(szXptiDat, sizeof(szXptiDat), "xpti.dat"); AssertRCReturn(vrc, NS_ERROR_FAILURE); +#endif LogFlowFunc(("component registry : \"%s\"\n", szCompReg)); LogFlowFunc(("XPTI data file : \"%s\"\n", szXptiDat)); -#if defined (XPCOM_GLUE) - XPCOMGlueStartup(nsnull); -#endif - static const char *kAppPathsToProbe[] = { NULL, /* 0: will use VBOX_APP_HOME */ - NULL, /* 1: will try RTPathAppPrivateArch() */ -#ifdef RT_OS_LINUX - "/usr/lib/virtualbox", - "/opt/VirtualBox", -#elif RT_OS_SOLARIS - "/opt/VirtualBox/amd64", - "/opt/VirtualBox/i386", -#elif RT_OS_DARWIN - "/Application/VirtualBox.app/Contents/MacOS", -#endif + NULL, /* 1: will try RTPathAppPrivateArch(), correctly installed release builds will never go further */ + NULL, /* 2: will try parent directory of RTPathAppPrivateArch(), only for testcases in non-hardened builds */ + /* There used to be hard coded paths, but they only caused trouble + * because they often led to mixing of builds or even versions. + * If you feel tempted to add anything here, think again. They would + * only be used if option 1 would not work, which is a sign of a big + * problem, as it returns a fixed location defined at compile time. + * It is better to fail than blindly trying to cover the problem. */ }; /* Find out the directory where VirtualBox binaries are located */ @@ -393,11 +384,26 @@ HRESULT Initialize(bool fGui) vrc = RTPathAppPrivateArch(szAppHomeDir, sizeof(szAppHomeDir)); AssertRC(vrc); } + else if (i == 2) + { +#ifdef VBOX_WITH_HARDENING + continue; +#else /* !VBOX_WITH_HARDENING */ + /* Use parent of RTPathAppPrivateArch() if ends with "testcase" */ + vrc = RTPathAppPrivateArch(szAppHomeDir, sizeof(szAppHomeDir)); + AssertRC(vrc); + vrc = RTPathStripTrailingSlash(szAppHomeDir); + AssertRC(vrc); + char *filename = RTPathFilename(szAppHomeDir); + if (!filename || strcmp(filename, "testcase")) + continue; + RTPathStripFilename(szAppHomeDir); +#endif /* !VBOX_WITH_HARDENING */ + } else { /* Iterate over all other paths */ - szAppHomeDir[RTPATH_MAX - 1] = '\0'; - strncpy(szAppHomeDir, kAppPathsToProbe[i], RTPATH_MAX - 1); + RTStrCopy(szAppHomeDir, sizeof(szAppHomeDir), kAppPathsToProbe[i]); vrc = VINF_SUCCESS; } if (RT_FAILURE(vrc)) @@ -405,9 +411,14 @@ HRESULT Initialize(bool fGui) rc = NS_ERROR_FAILURE; continue; } - char szCompDir[RTPATH_MAX]; - vrc = RTPathAppend(strcpy(szCompDir, szAppHomeDir), sizeof(szCompDir), "components"); + vrc = RTStrCopy(szCompDir, sizeof(szCompDir), szAppHomeDir); + if (RT_FAILURE(vrc)) + { + rc = NS_ERROR_FAILURE; + continue; + } + vrc = RTPathAppend(szCompDir, sizeof(szCompDir), "components"); if (RT_FAILURE(vrc)) { rc = NS_ERROR_FAILURE; @@ -476,7 +487,9 @@ HRESULT Initialize(bool fGui) } /* clean up before the new try */ - rc = NS_ShutdownXPCOM(nsnull); + HRESULT rc2 = NS_ShutdownXPCOM(nsnull); + if (SUCCEEDED(rc)) + rc = rc2; if (i == 0) { @@ -485,20 +498,20 @@ HRESULT Initialize(bool fGui) } } -#endif /* !defined (VBOX_WITH_XPCOM) */ +#endif /* !defined(VBOX_WITH_XPCOM) */ + + AssertComRCReturnRC(rc); // for both COM and XPCOM, we only get here if this is the main thread; // only then initialize the autolock system (AutoLock.cpp) Assert(RTThreadIsMain(RTThreadSelf())); util::InitAutoLockSystem(); - AssertComRC(rc); - /* * Init the main event queue (ASSUMES it cannot fail). */ if (SUCCEEDED(rc)) - EventQueue::init(); + NativeEventQueue::init(); return rc; } @@ -516,14 +529,14 @@ HRESULT Shutdown() { if (-- gCOMMainInitCount == 0) { - EventQueue::uninit(); + NativeEventQueue::uninit(); ASMAtomicWriteHandle(&gCOMMainThread, NIL_RTTHREAD); } } CoUninitialize(); -#else /* !defined (VBOX_WITH_XPCOM) */ +#else /* !defined(VBOX_WITH_XPCOM) */ nsCOMPtr<nsIEventQueue> eventQ; rc = NS_GetMainEventQ(getter_AddRefs(eventQ)); @@ -555,7 +568,7 @@ HRESULT Shutdown() * init counter drops to zero */ if (--gXPCOMInitCount == 0) { - EventQueue::uninit(); + NativeEventQueue::uninit(); rc = NS_ShutdownXPCOM(nsnull); /* This is a thread initialized XPCOM and set gIsXPCOMInitialized to @@ -563,10 +576,6 @@ HRESULT Shutdown() bool wasInited = ASMAtomicXchgBool(&gIsXPCOMInitialized, false); Assert(wasInited == true); NOREF(wasInited); - -# if defined (XPCOM_GLUE) - XPCOMGlueShutdown(); -# endif } } } diff --git a/src/VBox/Main/glue/string.cpp b/src/VBox/Main/glue/string.cpp index dc15bddc..a5b95a1e 100644 --- a/src/VBox/Main/glue/string.cpp +++ b/src/VBox/Main/glue/string.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -57,7 +57,7 @@ void Bstr::copyFromN(const char *a_pszSrc, size_t a_cchMax) throw std::bad_alloc(); } - m_bstr = ::SysAllocStringByteLen(NULL, cwc * sizeof(OLECHAR)); + m_bstr = ::SysAllocStringByteLen(NULL, (unsigned)(cwc * sizeof(OLECHAR))); if (RT_UNLIKELY(!m_bstr)) throw std::bad_alloc(); diff --git a/src/VBox/Main/glue/tests/Makefile b/src/VBox/Main/glue/tests/Makefile index e1f0cb20..0b6f9096 100644 --- a/src/VBox/Main/glue/tests/Makefile +++ b/src/VBox/Main/glue/tests/Makefile @@ -2,7 +2,7 @@ # Makefile for a sample/testcase using the 'glue' Java API bindings # -# Copyright (C) 2010-2011 Oracle Corporation +# Copyright (C) 2010-2012 Oracle Corporation # # This file is part of VirtualBox Open Source Edition (OSE), as # available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Main/glue/tests/TestVBox.java b/src/VBox/Main/glue/tests/TestVBox.java index 0a703831..ce823720 100644 --- a/src/VBox/Main/glue/tests/TestVBox.java +++ b/src/VBox/Main/glue/tests/TestVBox.java @@ -4,7 +4,7 @@ * be used to connect to the webservice and (XP)COM APIs. */ /* - * Copyright (C) 2010-2011 Oracle Corporation + * Copyright (C) 2010-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -14,7 +14,7 @@ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -import org.virtualbox_4_2.*; +import org.virtualbox_4_3.*; import java.util.List; import java.util.Arrays; import java.math.BigInteger; @@ -25,7 +25,7 @@ public class TestVBox { System.out.println("got event: " + ev); VBoxEventType type = ev.getType(); - System.out.println("type = "+type); + System.out.println("type = " + type); switch (type) { case OnMachineStateChanged: @@ -34,7 +34,7 @@ public class TestVBox if (mcse == null) System.out.println("Cannot query an interface"); else - System.out.println("mid="+mcse.getMachineId()); + System.out.println("mid=" + mcse.getMachineId()); break; } } @@ -63,7 +63,7 @@ public class TestVBox es.registerListener(listener, Arrays.asList(VBoxEventType.Any), false); try { - for (int i=0; i<50; i++) + for (int i = 0; i < 50; i++) { System.out.print("."); IEvent ev = es.getEvent(listener, 500); @@ -97,6 +97,8 @@ public class TestVBox hwvirtEnabled = m.getHWVirtExProperty(HWVirtExPropertyType.Enabled); hwvirtNestedPaging = m.getHWVirtExProperty(HWVirtExPropertyType.NestedPaging); paeEnabled = m.getCPUProperty(CPUPropertyType.PAE); + String osType = m.getOSTypeId(); + IGuestOSType foo = vbox.getGuestOSType(osType); } catch (VBoxException e) { @@ -114,11 +116,29 @@ public class TestVBox } } + static boolean progressBar(VirtualBoxManager mgr, IProgress p, long waitMillis) + { + long end = System.currentTimeMillis() + waitMillis; + while (!p.getCompleted()) + { + mgr.waitForEvents(0); + p.waitForCompletion(200); + if (System.currentTimeMillis() >= end) + return false; + } + return true; + } + static void testStart(VirtualBoxManager mgr, IVirtualBox vbox) { - String m = vbox.getMachines().get(0).getName(); - System.out.println("\nAttempting to start VM '" + m + "'"); - mgr.startVm(m, null, 7000); + IMachine m = vbox.getMachines().get(0); + String name = m.getName(); + System.out.println("\nAttempting to start VM '" + name + "'"); + + ISession session = mgr.getSessionObject(); + IProgress p = m.launchVMProcess(session, "gui", ""); + progressBar(mgr, p, 10000); + session.unlockMachine(); } static void testMultiServer() @@ -130,11 +150,18 @@ public class TestVBox mgr1.connect("http://i7:18083", "", ""); mgr2.connect("http://main:18083", "", ""); - String mach1 = mgr1.getVBox().getMachines().get(0).getName(); - String mach2 = mgr2.getVBox().getMachines().get(0).getName(); - - mgr1.startVm(mach1, null, 7000); - mgr2.startVm(mach2, null, 7000); + IMachine m1 = mgr1.getVBox().getMachines().get(0); + IMachine m2 = mgr2.getVBox().getMachines().get(0); + String name1 = m1.getName(); + String name2 = m2.getName(); + ISession session1 = mgr1.getSessionObject(); + ISession session2 = mgr2.getSessionObject(); + IProgress p1 = m1.launchVMProcess(session1, "gui", ""); + IProgress p2 = m2.launchVMProcess(session2, "gui", ""); + progressBar(mgr1, p1, 10000); + progressBar(mgr2, p2, 10000); + session1.unlockMachine(); + session2.unlockMachine(); } finally { mgr1.cleanup(); mgr2.cleanup(); @@ -157,6 +184,23 @@ public class TestVBox } } + static void printErrorInfo(VBoxException e) + { + System.out.println("VBox error: " + e.getMessage()); + System.out.println("Error cause message: " + e.getCause()); + System.out.println("Overall result code: " + Integer.toHexString(e.getResultCode())); + int i = 1; + for (IVirtualBoxErrorInfo ei = e.getVirtualBoxErrorInfo(); ei != null; ei = ei.getNext(), i++) + { + System.out.println("Detail information #" + i); + System.out.println("Error mesage: " + ei.getText()); + System.out.println("Result code: " + Integer.toHexString(ei.getResultCode())); + // optional, usually provides little additional information: + System.out.println("Component: " + ei.getComponent()); + System.out.println("Interface ID: " + ei.getInterfaceID()); + } + } + public static void main(String[] args) { @@ -167,15 +211,15 @@ public class TestVBox String user = null; String passwd = null; - for (int i = 0; i<args.length; i++) + for (int i = 0; i < args.length; i++) { - if ("-w".equals(args[i])) + if (args[i].equals("-w")) ws = true; - else if ("-url".equals(args[i])) + else if (args[i].equals("-url")) url = args[++i]; - else if ("-user".equals(args[i])) + else if (args[i].equals("-user")) user = args[++i]; - else if ("-passwd".equals(args[i])) + else if (args[i].equals("-passwd")) passwd = args[++i]; } @@ -206,7 +250,13 @@ public class TestVBox } catch (VBoxException e) { - System.out.println("VBox error: "+e.getMessage()+" original="+e.getWrapped()); + printErrorInfo(e); + System.out.println("Java stack trace:"); + e.printStackTrace(); + } + catch (RuntimeException e) + { + System.out.println("Runtime error: " + e.getMessage()); e.printStackTrace(); } catch (java.io.IOException e) diff --git a/src/VBox/Main/glue/tests/TestVBoxNATEngine.java b/src/VBox/Main/glue/tests/TestVBoxNATEngine.java new file mode 100644 index 00000000..8f284205 --- /dev/null +++ b/src/VBox/Main/glue/tests/TestVBoxNATEngine.java @@ -0,0 +1,187 @@ +/* $Id: TestVBoxNATEngine.java $ */ + +/* Small sample/testcase which demonstrates that the same source code can + * be used to connect to the webservice and (XP)COM APIs. */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +import org.virtualbox_4_3.*; +import java.util.List; +import java.util.Arrays; +import java.util.Iterator; +import java.math.BigInteger; + +public class TestVBoxNATEngine +{ + void testEnumeration(VirtualBoxManager mgr, IVirtualBox vbox, IMachine vm) + { + String name; + boolean inaccessible = false; + /* different chipsets might have different number of attachments */ + ChipsetType chipsetType = vm.getChipsetType(); + INetworkAdapter adapters[] = + new INetworkAdapter[ + vbox.getSystemProperties().getMaxNetworkAdapters(chipsetType).intValue()]; + + try + { + name = vm.getName(); + /* + * Dump adapters and if it's got NAT attachment + * dump it settings + */ + + for (int nidx = 0; nidx < adapters.length; ++nidx) + { + /* select available and NATs only. */ + adapters[nidx] = vm.getNetworkAdapter(new Long(nidx)); + INetworkAdapter n = adapters[nidx]; + + if (n == null) + continue; + NetworkAttachmentType attachmentType = n.getAttachmentType(); + if (attachmentType.equals(NetworkAttachmentType.NAT)) + { + INATEngine nat = n.getNATEngine(); + List<String> portForward = nat.getRedirects(); + String pf = null; + Iterator<String> itPortForward = portForward.iterator(); + for (;itPortForward.hasNext();) + { + pf = itPortForward.next(); + System.out.println(name + ":NIC" + n.getSlot() /* name:NIC<slot number>*/ + + " pf: " + pf); /* port-forward rule */ + } + if (pf != null) + { + String pfAttributes[] = pf.split(","); + /* name,proto,hostip,host,hostport,guestip,guestport */ + nat.removeRedirect(pfAttributes[0]); + nat.addRedirect("", + NATProtocol.fromValue(new Integer(pfAttributes[1]).longValue()), + pfAttributes[2], + new Integer( + new Integer(pfAttributes[3]).intValue() + 1), + pfAttributes[4], + new Integer(pfAttributes[5])); + } + + } + } + + } + catch (VBoxException e) + { + name = "<inaccessible>"; + inaccessible = true; + } + } + + static void testStart(VirtualBoxManager mgr, IVirtualBox vbox, IMachine vm) + { + System.out.println("\nAttempting to start VM '" + vm.getName() + "'"); + mgr.startVm(vm.getName(), null, 7000); + } + + public TestVBoxNATEngine(String[] args) + { + VirtualBoxManager mgr = VirtualBoxManager.createInstance(null); + + boolean ws = false; + String url = null; + String user = null; + String passwd = null; + String vmname = null; + IMachine vm = null; + + for (int i = 0; i<args.length; i++) + { + if ("-w".equals(args[i])) + ws = true; + else if ("-url".equals(args[i])) + url = args[++i]; + else if ("-user".equals(args[i])) + user = args[++i]; + else if ("-passwd".equals(args[i])) + passwd = args[++i]; + else if ("-vm".equals(args[i])) + vmname = args[++i]; + } + + if (ws) + { + try { + mgr.connect(url, user, passwd); + } catch (VBoxException e) { + e.printStackTrace(); + System.out.println("Cannot connect, start webserver first!"); + } + } + + try + { + IVirtualBox vbox = mgr.getVBox(); + if (vbox != null) + { + if (vmname != null) + { + for (IMachine m:vbox.getMachines()) + { + if (m.getName().equals(vmname)) + { + vm = m; + break; + } + } + + } + else + vm = vbox.getMachines().get(0); + System.out.println("VirtualBox version: " + vbox.getVersion() + "\n"); + if (vm != null) + { + testEnumeration(mgr, vbox, vm); + testStart(mgr, vbox, vm); + //testEvents(mgr, vbox.getEventSource()); + } + System.out.println("done, press Enter..."); + int ch = System.in.read(); + } + } + catch (VBoxException e) + { + System.out.println("VBox error: "+e.getMessage()+" original="+e.getWrapped()); + e.printStackTrace(); + } + catch (java.io.IOException e) + { + e.printStackTrace(); + } + + if (ws) + { + try { + mgr.disconnect(); + } catch (VBoxException e) { + e.printStackTrace(); + } + } + /* cleanup do the disconnect */ + mgr.cleanup(); + + } + public static void main(String[] args) + { + new TestVBoxNATEngine(args); + } + +} diff --git a/src/VBox/Main/glue/vboxapi.py b/src/VBox/Main/glue/vboxapi.py index 66bc71bc..3cda567d 100755..100644 --- a/src/VBox/Main/glue/vboxapi.py +++ b/src/VBox/Main/glue/vboxapi.py @@ -1,5 +1,12 @@ +# -*- coding: utf-8 -*- +# $Id: vboxapi.py $ """ -Copyright (C) 2009-2012 Oracle Corporation +VirtualBox Python API Glue. +""" + +__copyright__ = \ +""" +Copyright (C) 2009-2013 Oracle Corporation This file is part of VirtualBox Open Source Edition (OSE), as available from http://www.virtualbox.org. This file is free software; @@ -9,30 +16,47 @@ Foundation, in version 2 as it comes in the "COPYING" file of the VirtualBox OSE distribution. VirtualBox OSE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. """ +__version__ = "$Revision: 91042 $" + + +# Note! To set Python bitness on OSX use 'export VERSIONER_PYTHON_PREFER_32_BIT=yes' -import sys,os + +# Standard Python imports. +import sys, os import traceback -# To set Python bitness on OSX use 'export VERSIONER_PYTHON_PREFER_32_BIT=yes' -VboxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None) -VboxSdkDir = os.environ.get("VBOX_SDK_PATH", None) +# +# Globals, environment and sys.path changes. +# +VBoxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None) +VBoxSdkDir = os.environ.get("VBOX_SDK_PATH", None) -if VboxBinDir is None: +if VBoxBinDir is None: # Will be set by the installer - VboxBinDir = "%VBOX_INSTALL_PATH%" + VBoxBinDir = "%VBOX_INSTALL_PATH%" +else: + VBoxBinDir = os.path.abspath(VBoxBinDir); -if VboxSdkDir is None: +if VBoxSdkDir is None: # Will be set by the installer - VboxSdkDir = "%VBOX_SDK_PATH%" + VBoxSdkDir = "%VBOX_SDK_PATH%" +else: + VBoxSdkDir = os.path.abspath(VBoxSdkDir); + +os.environ["VBOX_PROGRAM_PATH"] = VBoxBinDir +os.environ["VBOX_SDK_PATH"] = VBoxSdkDir +sys.path.append(VBoxBinDir) -os.environ["VBOX_PROGRAM_PATH"] = VboxBinDir -os.environ["VBOX_SDK_PATH"] = VboxSdkDir -sys.path.append(VboxBinDir) +# +# Import the generated VirtualBox constants. +# from VirtualBox_constants import VirtualBoxReflectionInfo -class PerfCollector: + +class PerfCollector(object): """ This class provides a wrapper over IPerformanceCollector in order to get more 'pythonic' interface. @@ -106,36 +130,265 @@ class PerfCollector: }) return out +# +# Attribute hacks. +# def ComifyName(name): - return name[0].capitalize()+name[1:] - -_COMForward = { 'getattr' : None, - 'setattr' : None} - -def CustomGetAttr(self, attr): - # fastpath - if self.__class__.__dict__.get(attr) != None: - return self.__class__.__dict__.get(attr) - - # try case-insensitivity workaround for class attributes (COM methods) - for k in self.__class__.__dict__.keys(): - if k.lower() == attr.lower(): - self.__class__.__dict__[attr] = self.__class__.__dict__[k] - return getattr(self, k) + return name[0].capitalize() + name[1:] + + +## This is for saving the original DispatchBaseClass __getattr__ and __setattr__ +# method references. +_g_dCOMForward = { + 'getattr': None, + 'setattr': None, +} + +def _CustomGetAttr(self, sAttr): + """ Our getattr replacement for DispatchBaseClass. """ + # Fastpath. + oRet = self.__class__.__dict__.get(sAttr); + if oRet != None: + return oRet; + + # Try case-insensitivity workaround for class attributes (COM methods). + sAttrLower = sAttr.lower(); + for sKey in self.__class__.__dict__.keys(): + if sKey.lower() == sAttrLower: + self.__class__.__dict__[sAttr] = self.__class__.__dict__[sKey] + return getattr(self, sKey) + + # Slow path. try: - return _COMForward['getattr'](self,ComifyName(attr)) + return _g_dCOMForward['getattr'](self, ComifyName(sAttr)) except AttributeError: - return _COMForward['getattr'](self,attr) + return _g_dCOMForward['getattr'](self, sAttr) -def CustomSetAttr(self, attr, value): +def _CustomSetAttr(self, sAttr, oValue): + """ Our setattr replacement for DispatchBaseClass. """ try: - return _COMForward['setattr'](self, ComifyName(attr), value) + return _g_dCOMForward['setattr'](self, ComifyName(sAttr), oValue) except AttributeError: - return _COMForward['setattr'](self, attr, value) + return _g_dCOMForward['setattr'](self, sAttr, oValue) + + + +class PlatformBase(object): + """ + Base class for the platform specific code. + """ + + def __init__(self, aoParams): + _ = aoParams; + + def getVirtualBox(self): + """ + Gets a the IVirtualBox singleton. + """ + return None; + + def getSessionObject(self, oIVBox): + """ + Get a session object that can be used for opening machine sessions. + + The oIVBox parameter is an getVirtualBox() return value, i.e. an + IVirtualBox reference. + + See also openMachineSession. + """ + _ = oIVBox; + return None; + + def getType(self): + """ Returns the platform type (class name sans 'Platform'). """ + return None; + + def isRemote(self): + """ + Returns True if remote (web services) and False if local (COM/XPCOM). + """ + return False + + def getArray(self, oInterface, sAttrib): + """ + Retrives the value of the array attribute 'sAttrib' from + interface 'oInterface'. + + This is for hiding platform specific differences in attributes + returning arrays. + """ + _ = oInterface; + _ = sAttrib; + return None; + + def initPerThread(self): + """ + Does backend specific initialization for the calling thread. + """ + return True; + + def deinitPerThread(self): + """ + Does backend specific uninitialization for the calling thread. + """ + return True; + + def createListener(self, oImplClass, dArgs): + """ + Instantiates and wraps an active event listener class so it can be + passed to an event source for registration. + + oImplClass is a class (type, not instance) which implements + IEventListener. + + dArgs is a dictionary with string indexed variables. This may be + modified by the method to pass platform specific parameters. Can + be None. + + This currently only works on XPCOM. COM support is not possible due to + shortcuts taken in the COM bridge code, which is not under our control. + Use passive listeners for COM and web services. + """ + _ = oImplClass; + _ = dArgs; + raise Exception("No active listeners for this platform"); + return None; + + def waitForEvents(self, cMsTimeout): + """ + Wait for events to arrive and process them. + + The timeout (cMsTimeout) is in milliseconds for how long to wait for + events to arrive. A negative value means waiting for ever, while 0 + does not wait at all. + + Returns 0 if events was processed. + Returns 1 if timed out or interrupted in some way. + Returns 2 on error (like not supported for web services). + + Raises an exception if the calling thread is not the main thread (the one + that initialized VirtualBoxManager) or if the time isn't an integer. + """ + _ = cMsTimeout; + return 2; + + def interruptWaitEvents(self): + """ + Interrupt a waitForEvents call. + This is normally called from a worker thread to wake up the main thread. + + Returns True on success, False on failure. + """ + return False; + + def deinit(self): + """ + Unitializes the platform specific backend. + """ + return None; + + def queryInterface(self, oIUnknown, sClassName): + """ + IUnknown::QueryInterface wrapper. + + oIUnknown is who to ask. + sClassName is the name of the interface we're asking for. + """ + return None; + + # + # Error (exception) access methods. + # + + def xcptGetStatus(self, oXcpt): + """ + Returns the COM status code from the VBox API given exception. + """ + return None; + + def xcptIsDeadInterface(self, oXcpt): + """ + Returns True if the exception indicates that the interface is dead, False if not. + """ + return False; + + def xcptIsEqual(self, oXcpt, hrStatus): + """ + Checks if the exception oXcpt is equal to the COM/XPCOM status code + hrStatus. + + The oXcpt parameter can be any kind of object, we'll just return True + if it doesn't behave like a our exception class. + + Will not raise any exception as long as hrStatus and self are not bad. + """ + try: + hrXcpt = self.xcptGetStatus(oXcpt); + except AttributeError: + return False; + if hrXcpt == hrStatus: + return True; + + # Fudge for 32-bit signed int conversion. + if hrStatus > 0x7fffffff and hrStatus <= 0xffffffff and hrXcpt < 0: + if (hrStatus - 0x100000000) == hrXcpt: + return True; + return False; + + def xcptGetMessage(self, oXcpt): + """ + Returns the best error message found in the COM-like exception. + Returns None to fall back on xcptToString. + Raises exception if oXcpt isn't our kind of exception object. + """ + return None; + + def xcptGetBaseXcpt(self): + """ + Returns the base exception class. + """ + return None; + + def xcptSetupConstants(self, oDst): + """ + Copy/whatever all error constants onto oDst. + """ + return oDst; + + @staticmethod + def xcptCopyErrorConstants(oDst, oSrc): + """ + Copy everything that looks like error constants from oDst to oSrc. + """ + for sAttr in dir(oSrc): + if sAttr[0].isupper() and (sAttr[1].isupper() or sAttr[1] == '_'): + oAttr = getattr(oSrc, sAttr); + if type(oAttr) is int: + setattr(oDst, sAttr, oAttr); + return oDst; + + + +class PlatformMSCOM(PlatformBase): + """ + Platform specific code for MS COM. + """ + + ## @name VirtualBox COM Typelib definitions (should be generate) + # + # @remarks Must be updated when the corresponding VirtualBox.xidl bits + # are changed. Fortunately this isn't very often. + # @{ + VBOX_TLB_GUID = '{D7569351-1750-46F0-936E-BD127D5BC264}' + VBOX_TLB_LCID = 0 + VBOX_TLB_MAJOR = 1 + VBOX_TLB_MINOR = 3 + ## @} + + + class ConstantFake(object): + """ Class to fake access to constants in style of foo.bar.boo """ -class PlatformMSCOM: - # Class to fake access to constants in style of foo.bar.boo - class ConstantFake: def __init__(self, parent, name): self.__dict__['_parent'] = parent self.__dict__['_name'] = name @@ -172,7 +425,7 @@ class PlatformMSCOM: else: name = attr return win32com.client.constants.__getattr__(name) - except AttributeError,e: + except AttributeError, e: fake = PlatformMSCOM.ConstantFake(self, attr) consts[attr] = fake return fake @@ -189,39 +442,90 @@ class PlatformMSCOM: raise AttributeError try: return win32com.client.constants.__getattr__(a) - except AttributeError,e: + except AttributeError, e: return self.__dict__['_rootFake'].__getattr__(a) - VBOX_TLB_GUID = '{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}' - VBOX_TLB_LCID = 0 - VBOX_TLB_MAJOR = 1 - VBOX_TLB_MINOR = 0 + def __init__(self, dParams): + PlatformBase.__init__(self, dParams); - def __init__(self, params): - from win32com import universal - from win32com.client import gencache, DispatchBaseClass - from win32com.client import constants, getevents - import win32com - import pythoncom - import win32api - from win32con import DUPLICATE_SAME_ACCESS - from win32api import GetCurrentThread,GetCurrentThreadId,DuplicateHandle,GetCurrentProcess - import threading - pid = GetCurrentProcess() - self.tid = GetCurrentThreadId() - handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS) - self.handles = [] - self.handles.append(handle) - _COMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__'] - DispatchBaseClass.__dict__['__getattr__'] = CustomGetAttr - _COMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__'] - DispatchBaseClass.__dict__['__setattr__'] = CustomSetAttr - win32com.client.gencache.EnsureDispatch('VirtualBox.Session') - win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox') - self.oIntCv = threading.Condition() - self.fInterrupted = False; - - def getSessionObject(self, vbox): + # + # Since the code runs on all platforms, we have to do a lot of + # importing here instead of at the top of the file where it's normally located. + # + from win32com import universal + from win32com.client import gencache, DispatchBaseClass + from win32com.client import constants, getevents + import win32com + import pythoncom + import win32api + import winerror + from win32con import DUPLICATE_SAME_ACCESS + from win32api import GetCurrentThread, GetCurrentThreadId, DuplicateHandle, GetCurrentProcess + import threading + + self.winerror = winerror; + + pid = GetCurrentProcess() + self.tid = GetCurrentThreadId() + handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS) + self.handles = [] + self.handles.append(handle) + + # Hack the COM dispatcher base class so we can modify method and + # attribute names to match those in xpcom. + if _g_dCOMForward['setattr'] is None: + _g_dCOMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__'] + DispatchBaseClass.__dict__['__getattr__'] = _CustomGetAttr + _g_dCOMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__'] + DispatchBaseClass.__dict__['__setattr__'] = _CustomSetAttr + + # Hack the exception base class so the users doesn't need to check for + # XPCOM or COM and do different things. + ## @todo + + # + # Make sure the gencache is correct (we don't quite follow the COM + # versioning rules). + # + self.flushGenPyCache(win32com.client.gencache); + win32com.client.gencache.EnsureDispatch('VirtualBox.Session'); + win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox'); + + self.oIntCv = threading.Condition() + self.fInterrupted = False; + + _ = dParams; + + def flushGenPyCache(self, oGenCache): + """ + Flushes VBox related files in the win32com gen_py cache. + + This is necessary since we don't follow the typelib versioning rules + that everyeone else seems to subscribe to. + """ + # + # The EnsureModule method have broken validation code, it doesn't take + # typelib module directories into account. So we brute force them here. + # (It's possible the directory approach is from some older pywin + # version or the result of runnig makepy or gencache manually, but we + # need to cover it as well.) + # + sName = oGenCache.GetGeneratedFileName(self.VBOX_TLB_GUID, self.VBOX_TLB_LCID, + self.VBOX_TLB_MAJOR, self.VBOX_TLB_MINOR); + sGenPath = oGenCache.GetGeneratePath(); + if len(sName) > 36 and len(sGenPath) > 5: + sTypelibPath = os.path.join(sGenPath, sName); + if os.path.isdir(sTypelibPath): + import shutil; + shutil.rmtree(sTypelibPath, ignore_errors = True); + + # + # Ensure that our typelib is valid. + # + return oGenCache.EnsureModule(self.VBOX_TLB_GUID, self.VBOX_TLB_LCID, self.VBOX_TLB_MAJOR, self.VBOX_TLB_MINOR); + + def getSessionObject(self, oIVBox): + _ = oIVBox import win32com from win32com.client import Dispatch return win32com.client.Dispatch("VirtualBox.Session") @@ -234,11 +538,8 @@ class PlatformMSCOM: def getType(self): return 'MSCOM' - def getRemote(self): - return False - - def getArray(self, obj, field): - return obj.__getattr__(field) + def getArray(self, oInterface, sAttrib): + return oInterface.__getattr__(sAttrib) def initPerThread(self): import pythoncom @@ -248,11 +549,18 @@ class PlatformMSCOM: import pythoncom pythoncom.CoUninitialize() - def createListener(self, impl, arg): + def createListener(self, oImplClass, dArgs): + if True: + raise Exception('no active listeners on Windows as PyGatewayBase::QueryInterface() ' + 'returns new gateway objects all the time, thus breaking EventQueue ' + 'assumptions about the listener interface pointer being constants between calls '); + # Did this code ever really work? d = {} - d['BaseClass'] = impl - d['arg'] = arg - d['tlb_guid'] = PlatformMSCOM.VBOX_TLB_GUID + d['BaseClass'] = oImplClass + d['dArgs'] = dArgs + d['tlb_guid'] = PlatformMSCOM.VBOX_TLB_GUID + d['tlb_major'] = PlatformMSCOM.VBOX_TLB_MAJOR + d['tlb_minor'] = PlatformMSCOM.VBOX_TLB_MINOR str = "" str += "import win32com.server.util\n" str += "import pythoncom\n" @@ -260,16 +568,16 @@ class PlatformMSCOM: str += "class ListenerImpl(BaseClass):\n" str += " _com_interfaces_ = ['IEventListener']\n" str += " _typelib_guid_ = tlb_guid\n" - str += " _typelib_version_ = 1, 0\n" + str += " _typelib_version_ = tlb_major, tlb_minor\n" str += " _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER\n" # Maybe we'd better implement Dynamic invoke policy, to be more flexible here str += " _reg_policy_spec_ = 'win32com.server.policy.EventHandlerPolicy'\n" # capitalized version of listener method str += " HandleEvent=BaseClass.handleEvent\n" - str += " def __init__(self): BaseClass.__init__(self, arg)\n" + str += " def __init__(self): BaseClass.__init__(self, dArgs)\n" str += "result = win32com.server.util.wrap(ListenerImpl())\n" - exec (str,d,d) + exec(str, d, d) return d['result'] def waitForEvents(self, timeout): @@ -285,8 +593,10 @@ class PlatformMSCOM: if (self.tid != GetCurrentThreadId()): raise Exception("wait for events from the same thread you inited!") - if timeout < 0: cMsTimeout = INFINITE - else: cMsTimeout = timeout + if timeout < 0: + cMsTimeout = INFINITE + else: + cMsTimeout = timeout rc = MsgWaitForMultipleObjects(self.handles, 0, cMsTimeout, QS_ALLINPUT) if rc >= WAIT_OBJECT_0 and rc < WAIT_OBJECT_0+len(self.handles): # is it possible? @@ -310,7 +620,7 @@ class PlatformMSCOM: def interruptWaitEvents(self): """ - Basically a python implementation of EventQueue::postEvent(). + Basically a python implementation of NativeEventQueue::postEvent(). The magic value must be in sync with the C++ implementation or this won't work. @@ -340,18 +650,83 @@ class PlatformMSCOM: pythoncom.CoUninitialize() pass - def queryInterface(self, obj, klazzName): + def queryInterface(self, oIUnknown, sClassName): from win32com.client import CastTo - return CastTo(obj, klazzName) + return CastTo(oIUnknown, sClassName) + + def xcptGetStatus(self, oXcpt): + # The DISP_E_EXCEPTION + excptinfo fun needs checking up, only + # empirical info on it so far. + hrXcpt = oXcpt.hresult + if hrXcpt == self.winerror.DISP_E_EXCEPTION: + try: hrXcpt = oXcpt.excepinfo[5]; + except: pass; + return hrXcpt; + + def xcptIsDeadInterface(self, oXcpt): + return self.xcptGetStatus(oXcpt) in [ + 0x800706ba, -2147023174, # RPC_S_SERVER_UNAVAILABLE. + 0x800706be, -2147023170, # RPC_S_CALL_FAILED. + 0x800706bf, -2147023169, # RPC_S_CALL_FAILED_DNE. + 0x80010108, -2147417848, # RPC_E_DISCONNECTED. + 0x800706b5, -2147023179, # RPC_S_UNKNOWN_IF + ]; + + + def xcptGetMessage(self, oXcpt): + if hasattr(oXcpt, 'excepinfo'): + try: + if len(oXcpt.excepinfo) >= 3: + sRet = oXcpt.excepinfo[2]; + if len(sRet) > 0: + return sRet[0:]; + except: + pass; + if hasattr(oXcpt, 'strerror'): + try: + sRet = oXcpt.strerror; + if len(sRet) > 0: + return sRet; + except: + pass; + return None; + + def xcptGetBaseXcpt(self): + import pythoncom; + return pythoncom.com_error; + + def xcptSetupConstants(self, oDst): + import winerror; + oDst = self.xcptCopyErrorConstants(oDst, winerror); + + # XPCOM compatability constants. + oDst.NS_OK = oDst.S_OK; + oDst.NS_ERROR_FAILURE = oDst.E_FAIL; + oDst.NS_ERROR_ABORT = oDst.E_ABORT; + oDst.NS_ERROR_NULL_POINTER = oDst.E_POINTER; + oDst.NS_ERROR_NO_INTERFACE = oDst.E_NOINTERFACE; + oDst.NS_ERROR_INVALID_ARG = oDst.E_INVALIDARG; + oDst.NS_ERROR_OUT_OF_MEMORY = oDst.E_OUTOFMEMORY; + oDst.NS_ERROR_NOT_IMPLEMENTED = oDst.E_NOTIMPL; + oDst.NS_ERROR_UNEXPECTED = oDst.E_UNEXPECTED; + return oDst; + + +class PlatformXPCOM(PlatformBase): + """ + Platform specific code for XPCOM. + """ -class PlatformXPCOM: - def __init__(self, params): - sys.path.append(VboxSdkDir+'/bindings/xpcom/python/') + def __init__(self, dParams): + PlatformBase.__init__(self, dParams); + sys.path.append(VBoxSdkDir+'/bindings/xpcom/python/') import xpcom.vboxxpcom import xpcom import xpcom.components + _ = dParams; - def getSessionObject(self, vbox): + def getSessionObject(self, oIVBox): + _ = oIVBox; import xpcom.components return xpcom.components.classes["@virtualbox.org/Session;1"].createInstance() @@ -362,11 +737,8 @@ class PlatformXPCOM: def getType(self): return 'XPCOM' - def getRemote(self): - return False - - def getArray(self, obj, field): - return obj.__getattr__('get'+ComifyName(field))() + def getArray(self, oInterface, sAttrib): + return oInterface.__getattr__('get'+ComifyName(sAttrib))() def initPerThread(self): import xpcom @@ -376,17 +748,17 @@ class PlatformXPCOM: import xpcom xpcom._xpcom.DetachThread() - def createListener(self, impl, arg): + def createListener(self, oImplClass, dArgs): d = {} - d['BaseClass'] = impl - d['arg'] = arg + d['BaseClass'] = oImplClass + d['dArgs'] = dArgs str = "" str += "import xpcom.components\n" str += "class ListenerImpl(BaseClass):\n" str += " _com_interfaces_ = xpcom.components.interfaces.IEventListener\n" - str += " def __init__(self): BaseClass.__init__(self, arg)\n" + str += " def __init__(self): BaseClass.__init__(self, dArgs)\n" str += "result = ListenerImpl()\n" - exec (str,d,d) + exec (str, d, d) return d['result'] def waitForEvents(self, timeout): @@ -401,33 +773,126 @@ class PlatformXPCOM: import xpcom xpcom._xpcom.DeinitCOM() - def queryInterface(self, obj, klazzName): + def queryInterface(self, oIUnknown, sClassName): import xpcom.components - return obj.queryInterface(getattr(xpcom.components.interfaces, klazzName)) + return oIUnknown.queryInterface(getattr(xpcom.components.interfaces, sClassName)) + + def xcptGetStatus(self, oXcpt): + return oXcpt.errno; -class PlatformWEBSERVICE: - def __init__(self, params): - sys.path.append(os.path.join(VboxSdkDir,'bindings', 'webservice', 'python', 'lib')) - #import VirtualBox_services + def xcptIsDeadInterface(self, oXcpt): + return self.xcptGetStatus(oXcpt) in [ + 0x80004004, -2147467260, # NS_ERROR_ABORT + 0x800706be, -2147023170, # NS_ERROR_CALL_FAILED (RPC_S_CALL_FAILED) + ]; + + def xcptGetMessage(self, oXcpt): + if hasattr(oXcpt, 'msg'): + try: + sRet = oXcpt.msg; + if len(sRet) > 0: + return sRet; + except: + pass; + return None; + + def xcptGetBaseXcpt(self): + import xpcom; + return xpcom.Exception; + + def xcptSetupConstants(self, oDst): + import xpcom; + oDst = self.xcptCopyErrorConstants(oDst, xpcom.nsError); + + # COM compatability constants. + oDst.E_ACCESSDENIED = -2147024891; # see VBox/com/defs.h + oDst.S_OK = oDst.NS_OK; + oDst.E_FAIL = oDst.NS_ERROR_FAILURE; + oDst.E_ABORT = oDst.NS_ERROR_ABORT; + oDst.E_POINTER = oDst.NS_ERROR_NULL_POINTER; + oDst.E_NOINTERFACE = oDst.NS_ERROR_NO_INTERFACE; + oDst.E_INVALIDARG = oDst.NS_ERROR_INVALID_ARG; + oDst.E_OUTOFMEMORY = oDst.NS_ERROR_OUT_OF_MEMORY; + oDst.E_NOTIMPL = oDst.NS_ERROR_NOT_IMPLEMENTED; + oDst.E_UNEXPECTED = oDst.NS_ERROR_UNEXPECTED; + oDst.DISP_E_EXCEPTION = -2147352567; # For COM compatability only. + return oDst; + + +class PlatformWEBSERVICE(PlatformBase): + """ + VirtualBox Web Services API specific code. + """ + + def __init__(self, dParams): + PlatformBase.__init__(self, dParams); + # Import web services stuff. Fix the sys.path the first time. + sWebServLib = os.path.join(VBoxSdkDir, 'bindings', 'webservice', 'python', 'lib'); + if sWebServLib not in sys.path: + sys.path.append(sWebServLib); import VirtualBox_wrappers from VirtualBox_wrappers import IWebsessionManager2 - if params is not None: - self.user = params.get("user", "") - self.password = params.get("password", "") - self.url = params.get("url", "") + # Initialize instance variables from parameters. + if dParams is not None: + self.user = dParams.get("user", "") + self.password = dParams.get("password", "") + self.url = dParams.get("url", "") else: - self.user = "" + self.user = "" self.password = "" - self.url = None - self.vbox = None + self.url = None + self.vbox = None + self.wsmgr = None; + + # + # Base class overrides. + # - def getSessionObject(self, vbox): - return self.wsmgr.getSessionObject(vbox) + def getSessionObject(self, oIVBox): + return self.wsmgr.getSessionObject(oIVBox) def getVirtualBox(self): return self.connect(self.url, self.user, self.password) + def getType(self): + return 'WEBSERVICE' + + def isRemote(self): + """ Returns True if remote VBox host, False if local. """ + return True + + def getArray(self, oInterface, sAttrib): + return oInterface.__getattr__(sAttrib) + + def waitForEvents(self, timeout): + # Webservices cannot do that yet + return 2; + + def interruptWaitEvents(self, timeout): + # Webservices cannot do that yet + return False; + + def deinit(self): + try: + disconnect() + except: + pass + + def queryInterface(self, oIUnknown, sClassName): + d = {} + d['oIUnknown'] = oIUnknown + str = "" + str += "from VirtualBox_wrappers import "+sClassName+"\n" + str += "result = "+sClassName+"(oIUnknown.mgr, oIUnknown.handle)\n" + # wrong, need to test if class indeed implements this interface + exec (str, d, d) + return d['result'] + + # + # Web service specific methods. + # + def connect(self, url, user, passwd): if self.vbox is not None: self.disconnect() @@ -449,164 +914,310 @@ class PlatformWEBSERVICE: def disconnect(self): if self.vbox is not None and self.wsmgr is not None: - self.wsmgr.logoff(self.vbox) - self.vbox = None - self.wsmgr = None + self.wsmgr.logoff(self.vbox) + self.vbox = None + self.wsmgr = None - def getType(self): - return 'WEBSERVICE' - def getRemote(self): - return True +## The current (last) exception class. +# This is reinitalized whenever VirtualBoxManager is called, so it will hold +# the reference to the error exception class for the last platform/style that +# was used. Most clients does talk to multiple VBox instance on different +# platforms at the same time, so this should be sufficent for most uses and +# be way simpler to use than VirtualBoxManager::oXcptClass. +CurXctpClass = None; - def getArray(self, obj, field): - return obj.__getattr__(field) - def initPerThread(self): - pass - - def deinitPerThread(self): - pass - - def createListener(self, impl, arg): - raise Exception("no active listeners for webservices") - - def waitForEvents(self, timeout): - # Webservices cannot do that yet - return 2; - - def interruptWaitEvents(self, timeout): - # Webservices cannot do that yet - return False; - - def deinit(self): - try: - disconnect() - except: - pass +class VirtualBoxManager(object): + """ + VirtualBox API manager class. - def queryInterface(self, obj, klazzName): - d = {} - d['obj'] = obj - str = "" - str += "from VirtualBox_wrappers import "+klazzName+"\n" - str += "result = "+klazzName+"(obj.mgr,obj.handle)\n" - # wrong, need to test if class indeed implements this interface - exec (str,d,d) - return d['result'] + The API users will have to instantiate this. If no parameters are given, + it will default to interface with the VirtualBox running on the local + machine. sStyle can be None (default), MSCOM, XPCOM or WEBSERVICES. Most + users will either be specifying None or WEBSERVICES. -class SessionManager: - def __init__(self, mgr): - self.mgr = mgr + The dPlatformParams is an optional dictionary for passing parameters to the + WEBSERVICE backend. + """ - def getSessionObject(self, vbox): - return self.mgr.platform.getSessionObject(vbox) + class Statuses(object): + def __init__(self): + pass; -class VirtualBoxManager: - def __init__(self, style, platparams): - if style is None: + def __init__(self, sStyle = None, dPlatformParams = None): + if sStyle is None: if sys.platform == 'win32': - style = "MSCOM" + sStyle = "MSCOM" else: - style = "XPCOM" - - - exec "self.platform = Platform"+style+"(platparams)" - # for webservices, enums are symbolic - self.constants = VirtualBoxReflectionInfo(style == "WEBSERVICE") - self.type = self.platform.getType() - self.remote = self.platform.getRemote() - self.style = style - self.mgr = SessionManager(self) - + sStyle = "XPCOM" + if sStyle == 'XPCOM': + self.platform = PlatformXPCOM(dPlatformParams); + elif sStyle == 'MSCOM': + self.platform = PlatformMSCOM(dPlatformParams); + elif sStyle == 'WEBSERVICE': + self.platform = PlatformWEBSERVICE(dPlatformParams); + else: + raise Exception('Unknown sStyle=%s' % (sStyle,)); + self.style = sStyle + self.type = self.platform.getType() + self.remote = self.platform.isRemote() + ## VirtualBox API constants (for webservices, enums are symbolic). + self.constants = VirtualBoxReflectionInfo(sStyle == "WEBSERVICE") + + ## Status constants. + self.statuses = self.platform.xcptSetupConstants(VirtualBoxManager.Statuses()); + ## @todo Add VBOX_E_XXX to statuses? They're already in constants... + ## Dictionary for errToString, built on demand. + self._dErrorValToName = None; + + ## The exception class for the selected platform. + self.oXcptClass = self.platform.xcptGetBaseXcpt(); + global CurXcptClass; + CurXcptClass = self.oXcptClass; + + # Get the virtualbox singleton. try: self.vbox = self.platform.getVirtualBox() - except NameError,ne: + except NameError, ne: print "Installation problem: check that appropriate libs in place" traceback.print_exc() raise ne - except Exception,e: - print "init exception: ",e + except Exception, e: + print "init exception: ", e traceback.print_exc() if self.remote: self.vbox = None else: raise e + ## @deprecated + # This used to refer to a session manager class with only one method + # called getSessionObject. The method has moved into this call. + self.mgr = self; + + def __del__(self): + self.deinit() - def getArray(self, obj, field): - return self.platform.getArray(obj, field) + def getPythonApiRevision(self): + """ + Returns a Python API revision number. + This will be incremented when features are added to this file. + """ + return 3; + + + # + # Wrappers for self.platform methods. + # def getVirtualBox(self): - return self.platform.getVirtualBox() + """ See PlatformBase::getVirtualBox(). """ + return self.platform.getVirtualBox() - def __del__(self): - self.deinit() + def getSessionObject(self, oIVBox): + """ See PlatformBase::getSessionObject(). """ + return self.platform.getSessionObject(oIVBox); + + def getArray(self, oInterface, sAttrib): + """ See PlatformBase::getArray(). """ + return self.platform.getArray(oInterface, sAttrib) + + def createListener(self, oImplClass, dArgs = None): + """ See PlatformBase::createListener(). """ + return self.platform.createListener(oImplClass, dArgs) + + def waitForEvents(self, cMsTimeout): + """ See PlatformBase::waitForEvents(). """ + return self.platform.waitForEvents(cMsTimeout) + + def interruptWaitEvents(self): + """ See PlatformBase::interruptWaitEvents(). """ + return self.platform.interruptWaitEvents() + + def queryInterface(self, oIUnknown, sClassName): + """ See PlatformBase::queryInterface(). """ + return self.platform.queryInterface(oIUnknown, sClassName) + + + # + # Init and uninit. + # + + def initPerThread(self): + """ See PlatformBase::deinitPerThread(). """ + self.platform.initPerThread() + + def deinitPerThread(self): + """ See PlatformBase::deinitPerThread(). """ + return self.platform.deinitPerThread() def deinit(self): + """ + For unitializing the manager. + Do not access it after calling this method. + """ if hasattr(self, "vbox"): del self.vbox self.vbox = None if hasattr(self, "platform"): self.platform.deinit() self.platform = None + return True; - def initPerThread(self): - self.platform.initPerThread() - def openMachineSession(self, mach, permitSharing = True): - session = self.mgr.getSessionObject(self.vbox) - if permitSharing: - type = self.constants.LockType_Shared - else: - type = self.constants.LockType_Write - mach.lockMachine(session, type) - return session + # + # Utility methods. + # - def closeMachineSession(self, session): - if session is not None: - session.unlockMachine() + def openMachineSession(self, oIMachine, fPermitSharing = True): + """ + Attemts to open the a session to the machine. + Returns a session object on success. + Raises exception on failure. + """ + oSession = self.mgr.getSessionObject(self.vbox); + if fPermitSharing: + type = self.constants.LockType_Shared; + else: + type = self.constants.LockType_Write; + oIMachine.lockMachine(oSession, type); + return oSession; - def deinitPerThread(self): - self.platform.deinitPerThread() + def closeMachineSession(self, oSession): + """ + Closes a session opened by openMachineSession. + Ignores None parameters. + """ + if oSession is not None: + oSession.unlockMachine() + return True; - def createListener(self, impl, arg = None): - return self.platform.createListener(impl, arg) + def getPerfCollector(self, oIVBox): + """ + Returns a helper class (PerfCollector) for accessing performance + collector goodies. See PerfCollector for details. + """ + return PerfCollector(self, oIVBox) - def waitForEvents(self, timeout): + def getBinDir(self): """ - Wait for events to arrive and process them. + Returns the VirtualBox binary directory. + """ + global VBoxBinDir + return VBoxBinDir - The timeout is in milliseconds. A negative value means waiting for - ever, while 0 does not wait at all. + def getSdkDir(self): + """ + Returns the VirtualBox SDK directory. + """ + global VBoxSdkDir + return VBoxSdkDir - Returns 0 if events was processed. - Returns 1 if timed out or interrupted in some way. - Returns 2 on error (like not supported for web services). - Raises an exception if the calling thread is not the main thread (the one - that initialized VirtualBoxManager) or if the time isn't an integer. + # + # Error code utilities. + # + + ## @todo port to webservices! + + def xcptGetStatus(self, oXcpt = None): + """ + Gets the status code from an exception. If the exception parameter + isn't specified, the current exception is examined. """ - return self.platform.waitForEvents(timeout) + if oXcpt is None: + oXcpt = sys.exc_info()[1]; + return self.platform.xcptGetStatus(oXcpt); - def interruptWaitEvents(self): + def xcptIsDeadInterface(self, oXcpt = None): """ - Interrupt a waitForEvents call. - This is normally called from a worker thread. + Returns True if the exception indicates that the interface is dead, + False if not. If the exception parameter isn't specified, the current + exception is examined. + """ + if oXcpt is None: + oXcpt = sys.exc_info()[1]; + return self.platform.xcptIsDeadInterface(oXcpt); - Returns True on success, False on failure. + def xcptIsOurXcptKind(self, oXcpt = None): """ - return self.platform.interruptWaitEvents() + Checks if the exception is one that could come from the VBox API. If + the exception parameter isn't specified, the current exception is + examined. + """ + if self.oXcptClass is None: ## @todo find the exception class for web services! + return False; + if oXcpt is None: + oXcpt = sys.exc_info()[1]; + return isinstance(oXcpt, self.oXcptClass); - def getPerfCollector(self, vbox): - return PerfCollector(self, vbox) + def xcptIsEqual(self, oXcpt, hrStatus): + """ + Checks if the exception oXcpt is equal to the COM/XPCOM status code + hrStatus. - def getBinDir(self): - global VboxBinDir - return VboxBinDir + The oXcpt parameter can be any kind of object, we'll just return True + if it doesn't behave like a our exception class. If it's None, we'll + query the current exception and examine that. - def getSdkDir(self): - global VboxSdkDir - return VboxSdkDir + Will not raise any exception as long as hrStatus and self are not bad. + """ + if oXcpt is None: + oXcpt = sys.exc_info()[1]; + return self.platform.xcptIsEqual(oXcpt, hrStatus); + + def xcptIsNotEqual(self, oXcpt, hrStatus): + """ + Negated xcptIsEqual. + """ + return not self.xcptIsEqual(oXcpt, hrStatus); + + def xcptToString(self, hrStatusOrXcpt = None): + """ + Converts the specified COM status code, or the status code of the + specified exception, to a C constant string. If the parameter isn't + specified (is None), the current exception is examined. + """ + + # Deal with exceptions. + if hrStatusOrXcpt is None or self.xcptIsOurXcptKind(hrStatusOrXcpt): + hrStatus = self.xcptGetStatus(hrStatusOrXcpt); + else: + hrStatus = hrStatusOrXcpt; + + # Build the dictionary on demand. + if self._dErrorValToName is None: + dErrorValToName = dict(); + for sKey in dir(self.statuses): + if sKey[0].isupper(): + oValue = getattr(self.statuses, sKey); + if type(oValue) is int: + dErrorValToName[oValue] = sKey; + self._dErrorValToName = dErrorValToName; + + # Do the lookup, falling back on formatting the status number. + try: + sStr = self._dErrorValToName[int(hrStatus)]; + except KeyError: + hrLong = long(hrStatus); + sStr = '%#x (%d)' % (hrLong, hrLong); + return sStr; + + def xcptGetMessage(self, oXcpt = None): + """ + Returns the best error message found in the COM-like exception. If the + exception parameter isn't specified, the current exception is examined. + """ + if oXcpt is None: + oXcpt = sys.exc_info()[1]; + sRet = self.platform.xcptGetMessage(oXcpt); + if sRet is None: + sRet = self.xcptToString(oXcpt); + return sRet; + + # Legacy, remove in a day or two. + errGetStatus = xcptGetStatus + errIsDeadInterface = xcptIsDeadInterface + errIsOurXcptKind = xcptIsOurXcptKind + errGetMessage = xcptGetMessage - def queryInterface(self, obj, klazzName): - return self.platform.queryInterface(obj, klazzName) diff --git a/src/VBox/Main/glue/xpcom/helpers.cpp b/src/VBox/Main/glue/xpcom/helpers.cpp index 38ce7129..53f0ab5f 100644 --- a/src/VBox/Main/glue/xpcom/helpers.cpp +++ b/src/VBox/Main/glue/xpcom/helpers.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -139,6 +139,8 @@ int SysReAllocString(BSTR *pbstr, const OLECHAR *psz) return 1; } +#if 0 +/* Does not work -- we ignore newBuffer! */ /** * Changes the length of a previous created BSTR * @param pbstr string to change the length of @@ -167,6 +169,7 @@ int SysReAllocStringLen(BSTR *pbstr, const OLECHAR *psz, unsigned int cch) } return 1; } +#endif /** * Returns the string length in bytes without the terminator |