1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-/*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 package complex
.dispatches
;
20 // __________ Imports __________
22 // structs, const, ...
23 import com
.sun
.star
.beans
.PropertyValue
;
26 import com
.sun
.star
.frame
.DispatchDescriptor
;
27 import com
.sun
.star
.frame
.XDispatch
;
28 import com
.sun
.star
.frame
.XDispatchProvider
;
29 import com
.sun
.star
.frame
.XDispatchProviderInterceptor
;
30 import com
.sun
.star
.frame
.XInterceptorInfo
;
31 import com
.sun
.star
.frame
.XStatusListener
;
33 import com
.sun
.star
.lang
.XMultiServiceFactory
;
34 import com
.sun
.star
.awt
.XDataTransferProviderAccess
;
37 import com
.sun
.star
.util
.URL
;
38 import com
.sun
.star
.uno
.UnoRuntime
;
40 // __________ Implementation __________
43 * implements a configurable interceptor for dispatch events.
45 public class Interceptor
implements XDispatch
,
46 XDispatchProviderInterceptor
,
49 /** contains the list of interception URL schema's (wildcards are allowed there!)
50 supported by this interceptor. It can be set from outside.
51 If no external URLs are set, the default "*" is used instead.
52 That would have the same effect as if this implementation would not support the
53 interface XInterceptorInfo !
55 private String
[] m_lURLs4InterceptionInfo
= null;
59 /** These URL's will be blocked by this interceptor.
60 Can be set from outside. Every queryDispatch() for these
61 set of URL's will be answered with an empty dispatch object!
62 If no external URLs are set the default "*" is used instead.
63 So every incoming URL will be blocked .-)
65 private String
[] m_lURLs4Blocking
= null;
69 /** Every dispatch interceptor knows it's master and slave interceptor
70 of the dispatch chain. These values must be stupid handled .-)
71 They have to be set and reset in case the right interface methods are called.
72 Nothing more. It's not allowed to dispose() it.
73 The slave can be used inside queryDispatch() to forward requests,
74 which are not handled by this interceptor instance.
76 private XDispatchProvider m_xSlave
= null;
77 private XDispatchProvider m_xMaster
= null;
81 /** counts calls of setSlave...().
82 So the outside API test can use this value to know if this interceptor
83 was really added to the interceptor chain of OOo.
85 private int m_nRegistrationCount
= 0;
89 /** indicates if this interceptor object is currently part of the interceptor
90 chain of OOo. Only true if a valid slave or master dispatch is set on this
93 private boolean m_bIsRegistered
= false;
95 /** points to the global uno service manager. */
96 private XMultiServiceFactory m_xMSF
= null;
98 public Interceptor(XMultiServiceFactory xMSF
)
104 /** XInterceptorInfo */
105 public synchronized String
[] getInterceptedURLs()
107 return impl_getURLs4InterceptionInfo();
112 /** XDispatchProviderInterceptor */
113 public synchronized XDispatchProvider
getSlaveDispatchProvider()
115 System
.out
.println("Interceptor.getSlaveDispatchProvider() called");
121 /** XDispatchProviderInterceptor */
122 public synchronized XDispatchProvider
getMasterDispatchProvider()
124 System
.out
.println("Interceptor.getMasterDispatchProvider() called");
130 /** XDispatchProviderInterceptor */
131 public synchronized void setSlaveDispatchProvider(XDispatchProvider xSlave
)
133 System
.out
.println("Interceptor.setSlaveDispatchProvider("+xSlave
+") called");
137 ++m_nRegistrationCount
;
138 m_bIsRegistered
= true;
142 m_bIsRegistered
= false;
148 /** XDispatchProviderInterceptor */
149 public synchronized void setMasterDispatchProvider(XDispatchProvider xMaster
)
151 System
.out
.println("Interceptor.setMasterDispatchProvider("+xMaster
+") called");
155 private XDataTransferProviderAccess m_xToolkit
= null;
157 /** A beautiful method whose only purpose is to take and release a
158 * solar mutex. If this hangs - you can see a beautiful deadlock
159 * when you attach your debugger to the main process.
161 private void checkNoSolarMutexHeld()
165 if (m_xToolkit
== null)
166 m_xToolkit
= UnoRuntime
.queryInterface(
167 XDataTransferProviderAccess
.class,
168 m_xMSF
.createInstance("com.sun.star.awt.Toolkit"));
170 // A Method notable only for taking the solar mutex.
171 System
.out
.println("Check solarmutex not held - if so deadlock");
172 m_xToolkit
.getDragSource( null );
173 System
.out
.println("Solarmutex not held.");
174 } catch (java
.lang
.Throwable ex
) {
175 System
.out
.println("Failed to create and invoke toolkit method " + ex
.toString());
179 /** XDispatchProvider
181 public synchronized XDispatch
queryDispatch(URL aURL
,
182 String sTargetFrameName
,
185 System
.out
.println("Interceptor.queryDispatch('"+aURL
.Complete
+"', '"+sTargetFrameName
+"', "+nSearchFlags
+") called");
187 checkNoSolarMutexHeld();
189 if (impl_isBlockedURL(aURL
.Complete
))
191 System
.out
.println("Interceptor.queryDispatch(): URL blocked => returns NULL");
195 if (m_xSlave
!= null)
197 System
.out
.println("Interceptor.queryDispatch(): ask slave ...");
198 return m_xSlave
.queryDispatch(aURL
, sTargetFrameName
, nSearchFlags
);
201 System
.out
.println("Interceptor.queryDispatch(): no idea => returns this");
207 /** XDispatchProvider
209 public XDispatch
[] queryDispatches(DispatchDescriptor
[] lRequests
)
212 int c
= lRequests
.length
;
214 XDispatch
[] lResults
= new XDispatch
[c
];
217 lResults
[i
] = queryDispatch(lRequests
[i
].FeatureURL
,
218 lRequests
[i
].FrameName
,
219 lRequests
[i
].SearchFlags
);
229 public synchronized void dispatch(URL aURL
,
230 PropertyValue
[] lArguments
)
232 System
.out
.println("Interceptor.dispatch('"+aURL
.Complete
+"') called");
239 public synchronized void addStatusListener(XStatusListener xListener
,
240 com
.sun
.star
.util
.URL aURL
)
242 System
.out
.println("Interceptor.addStatusListener(..., '"+aURL
.Complete
+"') called");
249 public synchronized void removeStatusListener(XStatusListener xListener
,
250 com
.sun
.star
.util
.URL aURL
)
252 System
.out
.println("Interceptor.removeStatusListener(..., '"+aURL
.Complete
+"') called");
257 public synchronized int getRegistrationCount()
259 return m_nRegistrationCount
;
264 public synchronized boolean isRegistered()
266 return m_bIsRegistered
;
270 /** set a new list of URL's, which should be blocked by this interceptor.
271 (that's why it's necessary to call this impl-method before the interceptor
272 is used at the OOo API!)
274 public synchronized void setURLs4URLs4Blocking(String
[] lURLs
)
276 m_lURLs4Blocking
= lURLs
;
281 /** must be used internal to access the member m_lURLs4InterceptionInfo
283 - and to make sure it's initialized on demand
285 private synchronized String
[] impl_getURLs4InterceptionInfo()
287 if (m_lURLs4InterceptionInfo
== null)
289 m_lURLs4InterceptionInfo
= new String
[] { "*" };
292 return m_lURLs4InterceptionInfo
;
297 /** must be used internal to access the member m_lURLs4Blocking
299 - and to make sure it's initialized on demand
301 private synchronized String
[] impl_getURLs4Blocking()
303 if (m_lURLs4Blocking
== null)
305 m_lURLs4Blocking
= new String
[] { "*" };
308 return m_lURLs4Blocking
;
312 private boolean impl_isBlockedURL(String sURL
)
314 String
[] lBlockedURLs
= impl_getURLs4Blocking();
316 int c
= lBlockedURLs
.length
;
320 if (impl_match(sURL
, lBlockedURLs
[i
]))
331 private boolean impl_match(String sVal1
, String sVal2
)
333 // TODO implement wildcard match
334 return sVal1
.equals(sVal2
);
338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */