1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ProxyFactory.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 package com
.sun
.star
.lib
.uno
.bridges
.java_remote
;
33 import com
.sun
.star
.bridge
.XBridge
;
34 import com
.sun
.star
.lib
.util
.AsynchronousFinalizer
;
35 import com
.sun
.star
.uno
.IQueryInterface
;
36 import com
.sun
.star
.uno
.Type
;
37 import com
.sun
.star
.uno
.UnoRuntime
;
38 import java
.lang
.reflect
.InvocationHandler
;
39 import java
.lang
.reflect
.Method
;
40 import java
.lang
.reflect
.Proxy
;
43 * A factory for proxies specific to the <code>java_remote_bridge</code>.
45 * <p>Eventually, this class should be united with all other proxy classes
46 * specific to certain bridges (for example, the JNI bridge), resulting in a
47 * generic proxy class.</p>
49 final class ProxyFactory
{
50 public ProxyFactory(RequestHandler requestHandler
, XBridge bridge
) {
51 this.requestHandler
= requestHandler
;
55 public Object
create(String oid
, Type type
) {
56 return Proxy
.newProxyInstance(
57 getClass().getClassLoader(),
58 new Class
[] { com
.sun
.star
.lib
.uno
.Proxy
.class,
59 IQueryInterface
.class, type
.getZClass() },
60 new Handler(oid
, type
));
63 public boolean isProxy(Object obj
) {
64 if (Proxy
.isProxyClass(obj
.getClass())) {
65 InvocationHandler h
= Proxy
.getInvocationHandler(obj
);
66 return h
instanceof Handler
&& ((Handler
) h
).matches(this);
72 public static XBridge
getBridge(Object obj
) {
73 if (Proxy
.isProxyClass(obj
.getClass())) {
74 InvocationHandler h
= Proxy
.getInvocationHandler(obj
);
75 if (h
instanceof Handler
) {
76 return ((Handler
) h
).getBridge();
82 static int getDebugCount() {
83 synchronized (debugCountLock
) {
88 private static void incrementDebugCount() {
89 synchronized (debugCountLock
) {
94 private static void decrementDebugCount() {
95 synchronized (debugCountLock
) {
100 private final class Handler
implements InvocationHandler
{
101 public Handler(String oid
, Type type
) {
104 incrementDebugCount();
107 public boolean matches(ProxyFactory factory
) {
108 return ProxyFactory
.this == factory
;
111 public XBridge
getBridge() {
115 public Object
invoke(Object proxy
, Method method
, Object
[] args
)
118 if (method
.equals(METHOD_EQUALS
) || method
.equals(METHOD_IS_SAME
)) {
121 && oid
.equals(UnoRuntime
.generateOid(args
[0])));
122 } else if (method
.equals(METHOD_HASH_CODE
)) {
123 return new Integer(oid
.hashCode());
124 } else if (method
.equals(METHOD_TO_STRING
)) {
125 return "[Proxy:" + System
.identityHashCode(proxy
) + "," + oid
127 } else if (method
.equals(METHOD_QUERY_INTERFACE
)) {
128 // See the comment in java_remote_bridge.mapInterfaceTo for one
129 // reason why this implementation must not satisfy a request for
130 // a super-interface with a proxy itself:
131 return args
[0].equals(type
) ? proxy
132 : request("queryInterface", args
);
133 } else if (method
.equals(METHOD_GET_OID
)) {
136 return request(method
.getName(), args
);
140 protected void finalize() {
141 AsynchronousFinalizer
.add(new AsynchronousFinalizer
.Job() {
142 public void run() throws Throwable
{
144 request("release", null);
146 decrementDebugCount();
152 private Object
request(String operation
, Object
[] args
) throws Throwable
154 return requestHandler
.sendRequest(oid
, type
, operation
, args
);
157 private final String oid
;
158 private final Type type
;
161 private static final Method METHOD_EQUALS
;
162 private static final Method METHOD_HASH_CODE
;
163 private static final Method METHOD_TO_STRING
;
164 private static final Method METHOD_QUERY_INTERFACE
;
165 private static final Method METHOD_IS_SAME
;
166 private static final Method METHOD_GET_OID
;
169 METHOD_EQUALS
= Object
.class.getMethod(
170 "equals", new Class
[] { Object
.class });
171 METHOD_HASH_CODE
= Object
.class.getMethod("hashCode", null);
172 METHOD_TO_STRING
= Object
.class.getMethod("toString", null);
173 METHOD_QUERY_INTERFACE
= IQueryInterface
.class.getMethod(
174 "queryInterface", new Class
[] { Type
.class });
175 METHOD_IS_SAME
= IQueryInterface
.class.getMethod(
176 "isSame", new Class
[] { Object
.class });
177 METHOD_GET_OID
= IQueryInterface
.class.getMethod("getOid", null);
178 } catch (NoSuchMethodException e
) {
179 throw new ExceptionInInitializerError(e
);
183 private static final Object debugCountLock
= new Object();
184 private static int debugCount
= 0;
186 private final RequestHandler requestHandler
;
187 private final XBridge bridge
;