1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_stoc.hxx"
26 #include <osl/diagnose.h>
27 #include "tdmgr_common.hxx"
28 #include "tdmgr_tdenumeration.hxx"
29 
30 using namespace com::sun::star;
31 
32 extern rtl_StandardModuleCount g_moduleCount;
33 
34 namespace stoc_tdmgr
35 {
36 
37 //=========================================================================
38 //=========================================================================
39 //
40 // TypeDescriptionEnumerationImpl Implementation.
41 //
42 //=========================================================================
43 //=========================================================================
44 
TypeDescriptionEnumerationImpl(const rtl::OUString & rModuleName,const com::sun::star::uno::Sequence<com::sun::star::uno::TypeClass> & rTypes,com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,const TDEnumerationAccessStack & rTDEAS)45 TypeDescriptionEnumerationImpl::TypeDescriptionEnumerationImpl(
46         const rtl::OUString & rModuleName,
47         const com::sun::star::uno::Sequence<
48             com::sun::star::uno::TypeClass > & rTypes,
49         com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
50         const TDEnumerationAccessStack & rTDEAS )
51 : m_aModuleName( rModuleName ),
52   m_aTypes( rTypes ),
53   m_eDepth( eDepth ),
54   m_aChildren( rTDEAS )
55 {
56     ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
57 }
58 
59 //=========================================================================
60 // virtual
~TypeDescriptionEnumerationImpl()61 TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl()
62 {
63     ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
64 }
65 
66 //=========================================================================
67 //
68 // XEnumeration (base of XTypeDescriptionEnumeration) methods
69 //
70 //=========================================================================
71 
72 // virtual
hasMoreElements()73 sal_Bool SAL_CALL TypeDescriptionEnumerationImpl::hasMoreElements()
74     throw ( uno::RuntimeException )
75 {
76     uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
77         = queryCurrentChildEnumeration();
78     if ( xEnum.is() )
79         return xEnum->hasMoreElements();
80 
81     return sal_False;
82 }
83 
84 //=========================================================================
85 // virtual
nextElement()86 uno::Any SAL_CALL TypeDescriptionEnumerationImpl::nextElement()
87     throw ( container::NoSuchElementException,
88             lang::WrappedTargetException,
89             uno::RuntimeException )
90 {
91     uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
92         = queryCurrentChildEnumeration();
93     if ( xEnum.is() )
94         return xEnum->nextElement();
95 
96     throw container::NoSuchElementException(
97         rtl::OUString::createFromAscii(
98             "No further elements in enumeration!" ),
99         static_cast< cppu::OWeakObject * >( this  ) );
100 }
101 
102 //=========================================================================
103 //
104 // XTypeDescriptionEnumeration methods
105 //
106 //=========================================================================
107 
108 // virtual
109 uno::Reference< reflection::XTypeDescription > SAL_CALL
nextTypeDescription()110 TypeDescriptionEnumerationImpl::nextTypeDescription()
111     throw ( container::NoSuchElementException,
112             uno::RuntimeException )
113 {
114     uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
115         = queryCurrentChildEnumeration();
116     if ( xEnum.is() )
117         return xEnum->nextTypeDescription();
118 
119     throw container::NoSuchElementException(
120         rtl::OUString::createFromAscii(
121             "No further elements in enumeration!" ),
122         static_cast< cppu::OWeakObject * >( this  ) );
123 }
124 
125 //=========================================================================
126 uno::Reference< reflection::XTypeDescriptionEnumeration >
queryCurrentChildEnumeration()127 TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration()
128 {
129     osl::MutexGuard aGuard( m_aMutex );
130 
131     for (;;)
132     {
133         if ( m_xEnum.is() )
134         {
135             if ( m_xEnum->hasMoreElements() )
136             {
137                 return m_xEnum;
138             }
139             else
140             {
141                 // Forget about enumeration without further elements. Try next.
142                 m_xEnum.clear();
143             }
144         }
145 
146         // Note: m_xEnum is always null here.
147 
148         if ( m_aChildren.empty() )
149         {
150             // No child enumerations left.
151             return m_xEnum;
152         }
153 
154         try
155         {
156             m_xEnum =
157                 m_aChildren.top()->createTypeDescriptionEnumeration(
158                     m_aModuleName, m_aTypes, m_eDepth );
159         }
160         catch ( reflection::NoSuchTypeNameException const & )
161         {
162             OSL_ENSURE( sal_False,
163                "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
164                "- Caught NoSuchTypeNameException!" );
165         }
166         catch ( reflection::InvalidTypeNameException const & )
167         {
168             OSL_ENSURE( sal_False,
169                "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
170                "- Caught InvalidTypeNameException!" );
171         }
172 
173         // We're done with this enumeration access in any case (Either
174         // enumeration was successfully created or creation failed for some
175         // reason).
176         m_aChildren.pop();
177     }
178 
179     // unreachable
180 }
181 
182 } // namespace stoc_tdmgr
183 
184