Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License or as specified alternatively below. You may obtain a copy of
8 : * the License at http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Initial Developer of the Original Code is
16 : * Bjoern Michaelsen <bjoern.michaelsen@canonical.com>
17 : * Portions created by the Initial Developer are Copyright (C) 2010 the
18 : * Initial Developer. All Rights Reserved.
19 : *
20 : * Major Contributor(s):
21 : *
22 : * For minor contributions see the git repository.
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
26 : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
27 : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
28 : * instead of those above.
29 : */
30 :
31 : #include <ResourceIndexAccess.hxx>
32 :
33 : #include <com/sun/star/container/XIndexAccess.hpp>
34 : #include <com/sun/star/beans/PropertyValue.hpp>
35 : #include <comphelper/stlunosequence.hxx>
36 : #include <osl/mutex.hxx>
37 : #include <tools/rcid.h>
38 : #include <tools/resary.hxx>
39 : #include <tools/resmgr.hxx>
40 : #include <vcl/svapp.hxx>
41 :
42 : using namespace ::extensions::resource;
43 : using namespace ::com::sun::star::uno;
44 : using namespace ::com::sun::star::lang;
45 : using namespace ::com::sun::star::beans;
46 : using namespace ::com::sun::star::container;
47 :
48 : using ::comphelper::stl_begin;
49 : using ::comphelper::stl_end;
50 : using ::rtl::OString;
51 : using ::rtl::OUString;
52 : using ::rtl::OUStringToOString;
53 :
54 : namespace
55 : {
56 0 : static ::boost::shared_ptr<ResMgr> GetResMgr(Sequence<Any> const& rArgs)
57 : {
58 0 : if(rArgs.getLength()!=1)
59 0 : return ::boost::shared_ptr<ResMgr>();
60 0 : OUString sFilename;
61 0 : rArgs[0] >>= sFilename;
62 0 : SolarMutexGuard aGuard;
63 0 : const OString sEncName(OUStringToOString(sFilename, osl_getThreadTextEncoding()));
64 0 : return ::boost::shared_ptr<ResMgr>(ResMgr::CreateResMgr(sEncName.getStr()));
65 : }
66 :
67 0 : class ResourceIndexAccessBase : public cppu::WeakImplHelper1< ::com::sun::star::container::XIndexAccess>
68 : {
69 : public:
70 0 : ResourceIndexAccessBase( ::boost::shared_ptr<ResMgr> pResMgr)
71 0 : : m_pResMgr(pResMgr)
72 : {
73 : OSL_ENSURE(m_pResMgr, "no resource manager given");
74 0 : }
75 :
76 : // XIndexAccess
77 0 : virtual ::sal_Int32 SAL_CALL getCount( ) throw (::com::sun::star::uno::RuntimeException)
78 0 : { return m_pResMgr.get() ? SAL_MAX_UINT16 : 0; };
79 : // XElementAccess
80 0 : virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException)
81 0 : { return static_cast<bool>(m_pResMgr.get()); };
82 :
83 : protected:
84 : // m_pResMgr should never be NULL
85 : const ::boost::shared_ptr<ResMgr> m_pResMgr;
86 : };
87 :
88 0 : class ResourceStringIndexAccess : public ResourceIndexAccessBase
89 : {
90 : public:
91 0 : ResourceStringIndexAccess( ::boost::shared_ptr<ResMgr> pResMgr)
92 0 : : ResourceIndexAccessBase(pResMgr) {}
93 : // XIndexAccess
94 : virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
95 : // XElementAccessBase
96 0 : virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException)
97 0 : { return ::getCppuType(static_cast< ::rtl::OUString*>(0)); };
98 : };
99 :
100 0 : class ResourceStringListIndexAccess : public ResourceIndexAccessBase
101 : {
102 : public:
103 0 : ResourceStringListIndexAccess( ::boost::shared_ptr<ResMgr> pResMgr)
104 0 : : ResourceIndexAccessBase(pResMgr) {}
105 : // XIndexAccess
106 : virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
107 : // XElementAccessBase
108 0 : virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException)
109 0 : { return ::getCppuType(static_cast<Sequence<PropertyValue> * >(0)); };
110 : };
111 : }
112 :
113 0 : ResourceIndexAccess::ResourceIndexAccess(Sequence<Any> const& rArgs, Reference<XComponentContext> const&)
114 0 : : m_pResMgr(GetResMgr(rArgs))
115 0 : {};
116 :
117 0 : Reference<XInterface> initResourceIndexAccess(ResourceIndexAccess* pResourceIndexAccess)
118 : {
119 0 : Reference<XInterface> xResult(static_cast<cppu::OWeakObject*>(pResourceIndexAccess));
120 0 : if(!pResourceIndexAccess->hasElements())
121 : // xResult does not help the client to analyse the problem
122 : // and will crash on getByIndex calls, better just give back an empty Reference
123 : // so that such ResourceStringIndexAccess instances are never release into the wild
124 : throw RuntimeException(
125 : OUString(RTL_CONSTASCII_USTRINGPARAM("resource manager could not get initialized")),
126 0 : /* xResult */ Reference<XInterface>());
127 0 : return xResult;
128 : }
129 :
130 0 : Any SAL_CALL ResourceIndexAccess::getByName(const OUString& aName)
131 : throw (NoSuchElementException, WrappedTargetException, RuntimeException)
132 : {
133 0 : const Sequence<OUString> aNames(getElementNames());
134 0 : Reference<XIndexAccess> xResult;
135 0 : switch(::std::find(stl_begin(aNames), stl_end(aNames), aName)-stl_begin(aNames))
136 : {
137 : case 0:
138 0 : xResult = Reference<XIndexAccess>(new ResourceStringIndexAccess(m_pResMgr));
139 0 : break;
140 : case 1:
141 0 : xResult = Reference<XIndexAccess>(new ResourceStringListIndexAccess(m_pResMgr));
142 0 : break;
143 : default:
144 0 : throw NoSuchElementException();
145 : }
146 0 : return makeAny(xResult);
147 : }
148 :
149 0 : Sequence<OUString> SAL_CALL ResourceIndexAccess::getElementNames( )
150 : throw (RuntimeException)
151 : {
152 0 : static Sequence<OUString> aResult;
153 0 : if( aResult.getLength() == 0)
154 : {
155 0 : aResult.realloc(2);
156 0 : aResult[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("String"));
157 0 : aResult[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("StringList"));
158 : }
159 0 : return aResult;
160 : }
161 :
162 0 : ::sal_Bool SAL_CALL ResourceIndexAccess::hasByName(const OUString& aName)
163 : throw (RuntimeException)
164 : {
165 0 : const Sequence<OUString> aNames(getElementNames());
166 0 : return (::std::find(stl_begin(aNames), stl_end(aNames), aName) != stl_end(aNames));
167 : }
168 :
169 0 : Any SAL_CALL ResourceStringIndexAccess::getByIndex(sal_Int32 nIdx)
170 : throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
171 : {
172 0 : if(nIdx > SAL_MAX_UINT16 || nIdx < 0)
173 0 : throw IndexOutOfBoundsException();
174 0 : SolarMutexGuard aGuard;
175 0 : if(!m_pResMgr.get())
176 : throw RuntimeException(
177 : OUString(RTL_CONSTASCII_USTRINGPARAM("resource manager not available")),
178 0 : Reference<XInterface>());
179 :
180 0 : const ResId aId(static_cast<sal_uInt16>(nIdx), *m_pResMgr);
181 0 : aId.SetRT(RSC_STRING);
182 :
183 0 : if(!m_pResMgr->IsAvailable(aId))
184 : throw RuntimeException(
185 : OUString(RTL_CONSTASCII_USTRINGPARAM("string resource for id not available")),
186 0 : Reference<XInterface>());
187 :
188 0 : return makeAny(OUString(String(aId)));
189 : }
190 :
191 0 : Any SAL_CALL ResourceStringListIndexAccess::getByIndex(sal_Int32 nIdx)
192 : throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
193 : {
194 0 : if(nIdx > SAL_MAX_UINT16 || nIdx < 0)
195 0 : throw IndexOutOfBoundsException();
196 0 : SolarMutexGuard aGuard;
197 :
198 0 : if(!m_pResMgr.get())
199 : throw RuntimeException(
200 : OUString(RTL_CONSTASCII_USTRINGPARAM("resource manager not available")),
201 0 : Reference<XInterface>());
202 :
203 0 : const ResId aId(static_cast<sal_uInt16>(nIdx), *m_pResMgr);
204 0 : aId.SetRT(RSC_STRINGARRAY);
205 0 : if(!m_pResMgr->IsAvailable(aId))
206 : throw RuntimeException(
207 : OUString(RTL_CONSTASCII_USTRINGPARAM("string list resource for id not available")),
208 0 : Reference<XInterface>());
209 0 : const ResStringArray aStringList(aId);
210 0 : Sequence<PropertyValue> aPropList(aStringList.Count());
211 0 : for(sal_Int32 nCount = 0; nCount != aPropList.getLength(); ++nCount)
212 : {
213 0 : aPropList[nCount].Name = aStringList.GetString(nCount);
214 0 : aPropList[nCount].Handle = -1;
215 0 : aPropList[nCount].Value <<= aStringList.GetValue(nCount);
216 0 : aPropList[nCount].State = PropertyState_DIRECT_VALUE;
217 : }
218 0 : return makeAny(aPropList);
219 : }
220 :
221 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|