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_stoc.hxx"
30 #include <osl/diagnose.h>
31 #include "tdmgr_common.hxx"
32 #include "tdmgr_tdenumeration.hxx"
33 
34 using namespace com::sun::star;
35 
36 extern rtl_StandardModuleCount g_moduleCount;
37 
38 namespace stoc_tdmgr
39 {
40 
41 //=========================================================================
42 //=========================================================================
43 //
44 // TypeDescriptionEnumerationImpl Implementation.
45 //
46 //=========================================================================
47 //=========================================================================
48 
49 TypeDescriptionEnumerationImpl::TypeDescriptionEnumerationImpl(
50         const rtl::OUString & rModuleName,
51         const com::sun::star::uno::Sequence<
52             com::sun::star::uno::TypeClass > & rTypes,
53         com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
54         const TDEnumerationAccessStack & rTDEAS )
55 : m_aModuleName( rModuleName ),
56   m_aTypes( rTypes ),
57   m_eDepth( eDepth ),
58   m_aChildren( rTDEAS )
59 {
60     ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
61 }
62 
63 //=========================================================================
64 // virtual
65 TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl()
66 {
67     ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
68 }
69 
70 //=========================================================================
71 //
72 // XEnumeration (base of XTypeDescriptionEnumeration) methods
73 //
74 //=========================================================================
75 
76 // virtual
77 sal_Bool SAL_CALL TypeDescriptionEnumerationImpl::hasMoreElements()
78     throw ( uno::RuntimeException )
79 {
80     uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
81         = queryCurrentChildEnumeration();
82     if ( xEnum.is() )
83         return xEnum->hasMoreElements();
84 
85     return sal_False;
86 }
87 
88 //=========================================================================
89 // virtual
90 uno::Any SAL_CALL TypeDescriptionEnumerationImpl::nextElement()
91     throw ( container::NoSuchElementException,
92             lang::WrappedTargetException,
93             uno::RuntimeException )
94 {
95     uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
96         = queryCurrentChildEnumeration();
97     if ( xEnum.is() )
98         return xEnum->nextElement();
99 
100     throw container::NoSuchElementException(
101         rtl::OUString::createFromAscii(
102             "No further elements in enumeration!" ),
103         static_cast< cppu::OWeakObject * >( this  ) );
104 }
105 
106 //=========================================================================
107 //
108 // XTypeDescriptionEnumeration methods
109 //
110 //=========================================================================
111 
112 // virtual
113 uno::Reference< reflection::XTypeDescription > SAL_CALL
114 TypeDescriptionEnumerationImpl::nextTypeDescription()
115     throw ( container::NoSuchElementException,
116             uno::RuntimeException )
117 {
118     uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
119         = queryCurrentChildEnumeration();
120     if ( xEnum.is() )
121         return xEnum->nextTypeDescription();
122 
123     throw container::NoSuchElementException(
124         rtl::OUString::createFromAscii(
125             "No further elements in enumeration!" ),
126         static_cast< cppu::OWeakObject * >( this  ) );
127 }
128 
129 //=========================================================================
130 uno::Reference< reflection::XTypeDescriptionEnumeration >
131 TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration()
132 {
133     osl::MutexGuard aGuard( m_aMutex );
134 
135     for (;;)
136     {
137         if ( m_xEnum.is() )
138         {
139             if ( m_xEnum->hasMoreElements() )
140             {
141                 return m_xEnum;
142             }
143             else
144             {
145                 // Forget about enumeration without further elements. Try next.
146                 m_xEnum.clear();
147             }
148         }
149 
150         // Note: m_xEnum is always null here.
151 
152         if ( m_aChildren.empty() )
153         {
154             // No child enumerations left.
155             return m_xEnum;
156         }
157 
158         try
159         {
160             m_xEnum =
161                 m_aChildren.top()->createTypeDescriptionEnumeration(
162                     m_aModuleName, m_aTypes, m_eDepth );
163         }
164         catch ( reflection::NoSuchTypeNameException const & )
165         {
166             OSL_ENSURE( sal_False,
167                "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
168                "- Caught NoSuchTypeNameException!" );
169         }
170         catch ( reflection::InvalidTypeNameException const & )
171         {
172             OSL_ENSURE( sal_False,
173                "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
174                "- Caught InvalidTypeNameException!" );
175         }
176 
177         // We're done with this enumeration access in any case (Either
178         // enumeration was successfully created or creation failed for some
179         // reason).
180         m_aChildren.pop();
181     }
182 
183     // unreachable
184 }
185 
186 } // namespace stoc_tdmgr
187 
188