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_shell.hxx"
30 #include "internal/contentreader.hxx"
31 #include "dummytag.hxx"
32 #include "simpletag.hxx"
33 #include "autostyletag.hxx"
34 
35 #include "assert.h"
36 
37 /** constructor.
38 */
39 CContentReader::CContentReader( const std::string& DocumentName, LocaleSet_t const & DocumentLocale ):
40 CBaseReader( DocumentName )
41 {
42     try
43     {
44 		m_DefaultLocale = DocumentLocale;
45         Initialize( DOC_CONTENT_NAME );
46     }
47     catch(xml_parser_exception&
48     #if OSL_DEBUG_LEVEL > 0
49     ex
50     #endif
51     )
52     {
53         ENSURE(false, ex.what());
54     }
55     catch(...)
56     {
57         ENSURE(false, "Unknown error");
58     }
59 }
60 
61 CContentReader::CContentReader( void* stream, LocaleSet_t const & DocumentLocale, zlib_filefunc_def* fa ) :
62 CBaseReader( stream, fa )
63 {
64 try
65     {
66 		m_DefaultLocale = DocumentLocale;
67         Initialize( DOC_CONTENT_NAME );
68     }
69     catch(xml_parser_exception&
70     #if OSL_DEBUG_LEVEL > 0
71     ex
72     #endif
73     )
74     {
75         ENSURE(false, ex.what());
76     }
77     catch(...)
78     {
79         ENSURE(false, "Unknown error");
80     }
81 }
82 
83 
84 /** destructor.
85 */
86 
87 CContentReader::~CContentReader( void )
88 {
89 }
90 
91 /***********************   helper functions  ***********************/
92 
93 /** choose an appropriate tag reader
94 */
95 
96 ITag* CContentReader::chooseTagReader( const std::wstring& tag_name, const XmlTagAttributes_t& XmlAttributes )
97 {
98     if (( tag_name == CONTENT_TEXT_A )||( tag_name == CONTENT_TEXT_P )||
99 		( tag_name == CONTENT_TEXT_SPAN ) ||( tag_name == CONTENT_TEXT_H )||
100 		( tag_name == CONTENT_TEXT_SEQUENCE ) ||( tag_name == CONTENT_TEXT_BOOKMARK_REF )||
101 		( tag_name == CONTENT_TEXT_INDEX_TITLE_TEMPLATE ) )
102         return new CSimpleTag(XmlAttributes);
103     else if ( tag_name == CONTENT_STYLE_STYLE )
104     {
105         // if style:style | style:name is exist,, fill the style field, otherwise do nothing;
106         if  ( XmlAttributes.find(CONTENT_STYLE_STYLE_NAME) != XmlAttributes.end())
107 	        return new CAutoStyleTag(XmlAttributes);
108        else
109 	        return new CDummyTag();
110     }
111     else if ( ( tag_name == CONTENT_STYLE_PROPERTIES ) || ( tag_name == CONTENT_TEXT_STYLE_PROPERTIES ) )
112     {
113 		assert( !m_TagBuilderStack.empty() );
114 
115 		//here we presume that if CONTENT_STYLE_PROPERTIES tag is present, it just follow CONTENT_STYLE_STYLE;
116 		ITag* pTagBuilder = m_TagBuilderStack.top();
117 		pTagBuilder->addAttributes( XmlAttributes );
118 
119 	    return new CDummyTag();
120     }
121     else
122 	    return new CDummyTag();
123 }
124 
125 /** get style of the current content.
126 */
127 ::std::wstring CContentReader::getCurrentContentStyle( void )
128 {
129 	assert( !m_TagBuilderStack.empty() );
130 	ITag* pTagBuilder = m_TagBuilderStack.top();
131 
132 	return ( pTagBuilder->getTagAttribute(CONTENT_TEXT_STYLENAME) );
133 }
134 
135 /** add chunk into Chunk Buffer.
136 */
137 void CContentReader::addChunk( LocaleSet_t const & Locale, Content_t const & Content )
138 {
139 	if ( Content == EMPTY_STRING )
140 		return;
141 
142 	if ( ( ( m_ChunkBuffer.empty() ) || ( m_ChunkBuffer.back().first != Locale ) ) &&
143 		 ( ( Content != SPACE )  && ( Content != LF ) ) )
144 	{
145 		// if met a new locale, add a blank new chunk;
146 		Chunk_t Chunk;
147 		Chunk.first = Locale;
148 		Chunk.second = EMPTY_STRING;
149 		m_ChunkBuffer.push_back( Chunk );
150 	}
151 
152 	if ( !m_ChunkBuffer.empty() )
153 		m_ChunkBuffer.back().second += Content;
154 }
155 
156 /** get a style's locale field.
157 */
158 
159 LocaleSet_t const & CContentReader::getLocale( const StyleName_t Style )
160 {
161 	if ( m_StyleMap.empty() )
162 		return m_DefaultLocale;
163 
164 	StyleLocaleMap_t :: const_iterator style_Iter;
165 
166 	if ( ( style_Iter = m_StyleMap.find( Style ) ) == m_StyleMap.end( ) )
167 		return m_DefaultLocale;
168 	else
169 		return style_Iter->second;
170 
171 }
172 
173 /***********************   event handler functions  ***********************/
174 
175 //------------------------------
176 // start_element occurs when a tag is start
177 //------------------------------
178 
179 void CContentReader::start_element(
180     const std::wstring& /*raw_name*/,
181     const std::wstring& local_name,
182     const XmlTagAttributes_t& attributes)
183 {
184     //get appropriate Xml Tag Builder using MetaInfoBuilderFactory;
185     ITag* pTagBuilder = chooseTagReader( local_name,attributes );
186     assert( pTagBuilder != NULL );
187     pTagBuilder->startTag( );
188     m_TagBuilderStack.push( pTagBuilder );
189 
190 }
191 
192 //------------------------------
193 // end_element occurs when a tag is closed
194 //------------------------------
195 
196 void CContentReader::end_element(const std::wstring& /*raw_name*/, const std::wstring& local_name)
197 {
198     assert( !m_TagBuilderStack.empty() );
199     ITag* pTagBuilder = m_TagBuilderStack.top();
200 
201     if ( local_name == CONTENT_STYLE_STYLE )
202 	{
203 		StyleLocalePair_t StyleLocalePair = static_cast<CAutoStyleTag * >( pTagBuilder)->getStyleLocalePair();
204 		if ( ( static_cast<CAutoStyleTag * >( pTagBuilder)->isFull() ) && ( StyleLocalePair.second != m_DefaultLocale ) )
205 				m_StyleMap.insert( StyleLocalePair );
206 	}
207     if (( local_name == CONTENT_TEXT_A )||( local_name == CONTENT_TEXT_SPAN ) ||
208 		( local_name == CONTENT_TEXT_SEQUENCE )||( local_name == CONTENT_TEXT_BOOKMARK_REF ))
209 		addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( SPACE ) );
210     if ((( local_name == CONTENT_TEXT_P )||( local_name == CONTENT_TEXT_H ) ||
211 		 ( local_name == CONTENT_TEXT_INDEX_TITLE_TEMPLATE ) )&&
212 		( EMPTY_STRING != pTagBuilder->getTagContent( ) ) )
213 		addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( LF ) );
214 
215     m_TagBuilderStack.pop();
216     pTagBuilder->endTag();
217     delete pTagBuilder;
218 
219 }
220 
221 //------------------------------
222 // characters occurs when receiving characters
223 //------------------------------
224 
225 void CContentReader::characters( const std::wstring& character )
226 {
227     if ( character.length() > 0 && !HasOnlySpaces( character ) )
228     {
229 		addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( character ) );
230 
231         ITag* pTagBuilder = m_TagBuilderStack.top();
232         pTagBuilder->addCharacters( character );
233     }
234 }
235 
236