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/metainforeader.hxx"
31 #include "dummytag.hxx"
32 #include "simpletag.hxx"
33 #include "keywordstag.hxx"
34 
35 #include "assert.h"
36 
37 /** constructor.
38 */
39 CMetaInfoReader::CMetaInfoReader( const std::string& DocumentName ):
40 CBaseReader( DocumentName )
41 {
42     try
43     {
44 		m_pKeywords_Builder = new CKeywordsTag( );
45 		m_pSimple_Builder = new CSimpleTag( );
46 		m_pDummy_Builder   = new CDummyTag( );
47 
48         //retrieve all infomation that is useful
49         m_AllMetaInfo[META_INFO_AUTHOR]               = EMPTY_XML_TAG;
50         m_AllMetaInfo[META_INFO_TITLE]                = EMPTY_XML_TAG;
51         m_AllMetaInfo[META_INFO_SUBJECT]              = EMPTY_XML_TAG;
52         m_AllMetaInfo[META_INFO_KEYWORDS]             = EMPTY_XML_TAG;
53         m_AllMetaInfo[META_INFO_DESCRIPTION]          = EMPTY_XML_TAG;
54         m_AllMetaInfo[META_INFO_DOCUMENT_STATISTIC]   = EMPTY_XML_TAG;
55 
56         m_AllMetaInfo[META_INFO_GENERATOR]            = EMPTY_XML_TAG;
57         m_AllMetaInfo[META_INFO_CREATION]             = EMPTY_XML_TAG;
58         m_AllMetaInfo[META_INFO_CREATOR]              = EMPTY_XML_TAG;
59         m_AllMetaInfo[META_INFO_MODIFIED]             = EMPTY_XML_TAG;
60         m_AllMetaInfo[META_INFO_LANGUAGE]             = EMPTY_XML_TAG;
61         m_AllMetaInfo[META_INFO_DOCUMENT_NUMBER]      = EMPTY_XML_TAG;
62         m_AllMetaInfo[META_INFO_EDITING_TIME]         = EMPTY_XML_TAG;
63 
64 		Initialize( META_CONTENT_NAME );
65     }
66     catch(xml_parser_exception&
67     #if OSL_DEBUG_LEVEL > 0
68     ex
69     #endif
70     )
71     {
72         ENSURE(false, ex.what());
73     }
74     catch(...)
75     {
76         ENSURE(false, "Unknown error");
77     }
78 }
79 
80 CMetaInfoReader::CMetaInfoReader( void* stream, zlib_filefunc_def* fa) :
81 CBaseReader( stream, fa)
82 {
83 try
84     {
85 		m_pKeywords_Builder = new CKeywordsTag( );
86 		m_pSimple_Builder = new CSimpleTag( );
87 		m_pDummy_Builder   = new CDummyTag( );
88 
89         //retrieve all infomation that is useful
90         m_AllMetaInfo[META_INFO_AUTHOR]               = EMPTY_XML_TAG;
91         m_AllMetaInfo[META_INFO_TITLE]                = EMPTY_XML_TAG;
92         m_AllMetaInfo[META_INFO_SUBJECT]              = EMPTY_XML_TAG;
93         m_AllMetaInfo[META_INFO_KEYWORDS]             = EMPTY_XML_TAG;
94         m_AllMetaInfo[META_INFO_DESCRIPTION]          = EMPTY_XML_TAG;
95         m_AllMetaInfo[META_INFO_DOCUMENT_STATISTIC]   = EMPTY_XML_TAG;
96 
97         m_AllMetaInfo[META_INFO_GENERATOR]            = EMPTY_XML_TAG;
98         m_AllMetaInfo[META_INFO_CREATION]             = EMPTY_XML_TAG;
99         m_AllMetaInfo[META_INFO_CREATOR]              = EMPTY_XML_TAG;
100         m_AllMetaInfo[META_INFO_MODIFIED]             = EMPTY_XML_TAG;
101         m_AllMetaInfo[META_INFO_LANGUAGE]             = EMPTY_XML_TAG;
102         m_AllMetaInfo[META_INFO_DOCUMENT_NUMBER]      = EMPTY_XML_TAG;
103         m_AllMetaInfo[META_INFO_EDITING_TIME]         = EMPTY_XML_TAG;
104 
105 		Initialize( META_CONTENT_NAME );
106     }
107     catch(xml_parser_exception&
108     #if OSL_DEBUG_LEVEL > 0
109     ex
110     #endif
111     )
112     {
113         ENSURE(false, ex.what());
114     }
115     catch(...)
116     {
117         ENSURE(false, "Unknown error");
118     }
119 
120 }
121 
122 /** destructor.
123 */
124 
125 CMetaInfoReader::~CMetaInfoReader( void )
126 {
127     delete m_pKeywords_Builder;
128 	delete m_pSimple_Builder;
129     delete m_pDummy_Builder;
130 }
131 
132 
133 /***********************   export functions  ***********************/
134 
135 /** check if the Tag is in the target meta.xml file.
136 
137     @param TagName
138     the name of the tag that will be retrive.
139 */
140 bool CMetaInfoReader::hasTag( std::wstring TagName ) const
141 {
142     return ( m_AllMetaInfo.find(TagName) != m_AllMetaInfo.end());
143 }
144 
145 /** Get a specific tag content, compound tags will be returned as comma separated list.
146 
147     @param TagName
148     the name of the tag that will be retrive.
149 */
150 std::wstring CMetaInfoReader::getTagData( const std::wstring& TagName)
151 {
152     if( hasTag( TagName ) )
153         return m_AllMetaInfo[TagName].first;
154     else
155         return EMPTY_STRING;
156 }
157 
158 /** check if the a tag has the specific attribute.
159 
160     @param TagName
161     the name of the tag.
162     @param AttributeName
163     the name of the attribute.
164 */
165 bool CMetaInfoReader::hasTagAttribute( const std::wstring TagName,  std::wstring AttributeName)
166 {
167     return ( m_AllMetaInfo[TagName].second.find( AttributeName) != m_AllMetaInfo[TagName].second.end() );
168 }
169 
170 /** Get a specific attribute content.
171 
172     @param TagName
173     the name of the tag.
174     @param AttributeName
175     the name of the attribute.
176 */
177 std::wstring CMetaInfoReader::getTagAttribute( const std::wstring TagName,  std::wstring AttributeName)
178 {
179     if ( hasTagAttribute( TagName, AttributeName ) )
180         return  m_AllMetaInfo[ TagName ].second[AttributeName];
181     else
182         return EMPTY_STRING;
183 }
184 
185 /** helper function for getDefaultLocale().
186 */
187 const LocaleSet_t EN_US_LOCALE( ::std::make_pair( ::std::wstring( L"en" ),  ::std::wstring( L"US" )));
188 
189 bool isValidLocale ( ::std::wstring Locale )
190 {
191 	return ( Locale.length() == 5 );
192 }
193 
194 /** Get the default language of the whole document, if no such field, en-US is returned.
195 */
196 LocaleSet_t CMetaInfoReader::getDefaultLocale()
197 {
198     if (hasTag(META_INFO_LANGUAGE))
199     {
200 		::std::wstring locale = m_AllMetaInfo[META_INFO_LANGUAGE].first;
201 		return isValidLocale(locale) ? ::std::make_pair(locale.substr( 0,2), locale.substr( 3,2)) : EN_US_LOCALE;
202     }
203     else
204         return EN_US_LOCALE;
205 }
206 
207 /***********************   tag related functions  ***********************/
208 
209 /** choose an appropriate tag reader
210 */
211 
212 ITag* CMetaInfoReader::chooseTagReader( const std::wstring& tag_name, const XmlTagAttributes_t& XmlAttributes )
213 {
214 	if ( tag_name == META_INFO_KEYWORD )
215 	{
216 		m_AllMetaInfo[META_INFO_KEYWORDS].second = XmlAttributes;
217 		return m_pKeywords_Builder;
218 	}
219 	if (( tag_name == META_INFO_TITLE )||( tag_name == META_INFO_AUTHOR )||( tag_name == META_INFO_SUBJECT )||( tag_name == META_INFO_DESCRIPTION )||
220 		( tag_name == META_INFO_DOCUMENT_STATISTIC )||( tag_name == META_INFO_GENERATOR )||( tag_name == META_INFO_CREATION )||( tag_name == META_INFO_CREATOR )||
221 		( tag_name == META_INFO_MODIFIED )||( tag_name == META_INFO_LANGUAGE )||( tag_name == META_INFO_DOCUMENT_NUMBER )||( tag_name == META_INFO_EDITING_TIME ) )
222 	{
223 		m_AllMetaInfo[tag_name].second = XmlAttributes;
224 		return m_pSimple_Builder;
225 	}
226 	else
227         return m_pDummy_Builder;
228 
229 }
230 
231 //------------------------------
232 // save the received content into structure.
233 //------------------------------
234 void CMetaInfoReader::saveTagContent( const std::wstring& tag_name )
235 {
236 	ITag* pTagBuilder;
237 	if ( tag_name == META_INFO_KEYWORDS )
238         pTagBuilder = m_pKeywords_Builder;
239 	else if ( tag_name == META_INFO_KEYWORD )
240 	{
241 		// added for support for OASIS xml file format.
242 		m_AllMetaInfo[META_INFO_KEYWORDS].first =m_pKeywords_Builder->getTagContent( );
243 		return;
244 	}
245 	else if (( tag_name == META_INFO_TITLE )||( tag_name == META_INFO_AUTHOR )||( tag_name == META_INFO_SUBJECT )||( tag_name == META_INFO_DESCRIPTION )||
246 		( tag_name == META_INFO_DOCUMENT_STATISTIC )||( tag_name == META_INFO_GENERATOR )||( tag_name == META_INFO_CREATION )||( tag_name == META_INFO_CREATOR )||
247 		( tag_name == META_INFO_MODIFIED )||( tag_name == META_INFO_LANGUAGE )||( tag_name == META_INFO_DOCUMENT_NUMBER )||( tag_name == META_INFO_EDITING_TIME ) )
248         pTagBuilder = m_pSimple_Builder;
249 	else
250         pTagBuilder = m_pDummy_Builder;
251 
252 	m_AllMetaInfo[tag_name].first =pTagBuilder->getTagContent( );
253 }
254 
255 
256 /***********************   event handler functions  ***********************/
257 
258 //------------------------------
259 // start_element occurs when a tag is start
260 //------------------------------
261 
262 void CMetaInfoReader::start_element(
263 	const std::wstring& /*raw_name*/,
264 	const std::wstring& local_name,
265 	const XmlTagAttributes_t& attributes)
266 {
267 	//get appropriate Xml Tag Builder using MetaInfoBuilderFactory;
268 	ITag* pTagBuilder = chooseTagReader( local_name,attributes );
269     assert( pTagBuilder!= NULL );
270 	pTagBuilder->startTag( );
271 	m_TagBuilderStack.push( pTagBuilder );
272 
273 }
274 
275 //------------------------------
276 // end_element occurs when a tag is closed
277 //------------------------------
278 
279 void CMetaInfoReader::end_element(const std::wstring& /*raw_name*/, const std::wstring& local_name)
280 {
281 	assert( !m_TagBuilderStack.empty() );
282 	ITag* pTagBuilder = m_TagBuilderStack.top();
283 	m_TagBuilderStack.pop();
284 	pTagBuilder->endTag();
285 
286 	saveTagContent( local_name );
287 
288 }
289 
290 //------------------------------
291 // characters occurs when receiving characters
292 //------------------------------
293 
294 void CMetaInfoReader::characters( const std::wstring& character )
295 {
296 	if ( character.length() > 0 &&  !HasOnlySpaces( character ) )
297 	{
298 		ITag* pTagBuilder = m_TagBuilderStack.top();
299 		pTagBuilder->addCharacters( character );
300 	}
301 }
302 
303