1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cppuhelper.hxx"
30 
31 #include <rtl/bootstrap.hxx>
32 
33 #include <uno/mapping.hxx>
34 
35 #include <cppuhelper/factory.hxx>
36 #include <cppuhelper/compbase2.hxx>
37 #include <cppuhelper/component_context.hxx>
38 
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/util/XMacroExpander.hpp>
41 #include "com/sun/star/uno/RuntimeException.hpp"
42 
43 #include "macro_expander.hxx"
44 
45 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
46 #define SERVICE_NAME_A "com.sun.star.lang.MacroExpander"
47 #define SERVICE_NAME_B "com.sun.star.lang.BootstrapMacroExpander"
48 #define IMPL_NAME "com.sun.star.lang.comp.cppuhelper.BootstrapMacroExpander"
49 
50 
51 using namespace ::rtl;
52 using namespace ::osl;
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::uno;
55 
56 namespace cppu
57 {
58 //---- private forward -----------------------------------------------------------------------------
59 Bootstrap const & get_unorc() SAL_THROW( () );
60 }
61 
62 namespace cppuhelper { namespace detail {
63 
64 rtl::OUString expandMacros(rtl::OUString const & text) {
65     rtl::OUString t(text);
66     rtl_bootstrap_expandMacros_from_handle(
67         cppu::get_unorc().getHandle(), &t.pData);
68     return t;
69 }
70 
71 } }
72 
73 namespace
74 {
75 inline OUString s_impl_name() { return OUSTR(IMPL_NAME); }
76 static Sequence< OUString > const & s_get_service_names()
77 {
78     static Sequence< OUString > const * s_pnames = 0;
79     if (! s_pnames)
80     {
81         MutexGuard guard( Mutex::getGlobalMutex() );
82         if (! s_pnames)
83         {
84             static Sequence< OUString > s_names( 2 );
85             s_names[ 0 ] = OUSTR(SERVICE_NAME_A);
86             s_names[ 1 ] = OUSTR(SERVICE_NAME_B);
87             s_pnames = &s_names;
88         }
89     }
90     return *s_pnames;
91 }
92 
93 typedef ::cppu::WeakComponentImplHelper2<
94     util::XMacroExpander, lang::XServiceInfo > t_uno_impl;
95 
96 struct mutex_holder
97 {
98     Mutex m_mutex;
99 };
100 class Bootstrap_MacroExpander : public mutex_holder, public t_uno_impl
101 {
102 protected:
103     virtual void SAL_CALL disposing();
104 
105 public:
106     inline Bootstrap_MacroExpander( Reference< XComponentContext > const & ) SAL_THROW( () )
107         : t_uno_impl( m_mutex )
108         {}
109     virtual ~Bootstrap_MacroExpander()
110         SAL_THROW( () );
111 
112     // XMacroExpander impl
113     virtual OUString SAL_CALL expandMacros( OUString const & exp )
114         throw (lang::IllegalArgumentException);
115     // XServiceInfo impl
116     virtual OUString SAL_CALL getImplementationName()
117         throw (RuntimeException);
118     virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
119         throw (RuntimeException);
120     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
121         throw (RuntimeException);
122 };
123 
124 //__________________________________________________________________________________________________
125 void Bootstrap_MacroExpander::disposing()
126 {}
127 //__________________________________________________________________________________________________
128 Bootstrap_MacroExpander::~Bootstrap_MacroExpander() SAL_THROW( () )
129 {}
130 
131 // XServiceInfo impl
132 //__________________________________________________________________________________________________
133 OUString Bootstrap_MacroExpander::getImplementationName()
134     throw (RuntimeException)
135 {
136     return s_impl_name();
137 }
138 //__________________________________________________________________________________________________
139 sal_Bool Bootstrap_MacroExpander::supportsService( OUString const & serviceName )
140     throw (RuntimeException)
141 {
142     Sequence< OUString > const & service_names = s_get_service_names();
143     OUString const * p = service_names.getConstArray();
144     for ( sal_Int32 nPos = service_names.getLength(); nPos--; )
145     {
146         if (p[ nPos ].equals( serviceName ))
147             return sal_True;
148     }
149     return sal_False;
150 }
151 //__________________________________________________________________________________________________
152 Sequence< OUString > Bootstrap_MacroExpander::getSupportedServiceNames()
153     throw (RuntimeException)
154 {
155     return s_get_service_names();
156 }
157 
158 // XMacroExpander impl
159 //__________________________________________________________________________________________________
160 OUString Bootstrap_MacroExpander::expandMacros( OUString const & exp )
161     throw (lang::IllegalArgumentException)
162 {
163     return cppuhelper::detail::expandMacros( exp );
164 }
165 
166 //==================================================================================================
167 Reference< XInterface > SAL_CALL service_create(
168     Reference< XComponentContext > const & xComponentContext )
169     SAL_THROW( (RuntimeException) )
170 {
171     return static_cast< ::cppu::OWeakObject * >( new Bootstrap_MacroExpander( xComponentContext ) );
172 }
173 
174 }
175 
176 namespace cppu
177 {
178 
179 //##################################################################################################
180 Reference< lang::XSingleComponentFactory > create_boostrap_macro_expander_factory() SAL_THROW( () )
181 {
182 	Reference< lang::XSingleComponentFactory > free(::cppu::createSingleComponentFactory(
183 														service_create,
184 														s_impl_name(),
185 														s_get_service_names() ));
186 
187 	uno::Environment curr_env(Environment::getCurrent());
188 	uno::Environment target_env(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))));
189 
190 	uno::Mapping target2curr(target_env, curr_env);
191 
192 	return Reference<lang::XSingleComponentFactory>(
193 		reinterpret_cast<lang::XSingleComponentFactory *>(
194 			target2curr.mapInterface(free.get(), ::getCppuType(&free))),
195 		SAL_NO_ACQUIRE);
196 }
197 
198 }
199