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 #include "oox/core/relationshandler.hxx"
29 
30 #include <rtl/ustrbuf.hxx>
31 #include "oox/helper/attributelist.hxx"
32 
33 namespace oox {
34 namespace core {
35 
36 // ============================================================================
37 
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::xml::sax;
40 
41 using ::rtl::OUString;
42 using ::rtl::OUStringBuffer;
43 
44 // ============================================================================
45 
46 namespace {
47 
48 /*  Build path to relations file from passed fragment path, e.g.:
49         'path/path/file.xml'    -> 'path/path/_rels/file.xml.rels'
50         'file.xml'              -> '_rels/file.xml.rels'
51         ''                      -> '_rels/.rels'
52  */
53 OUString lclGetRelationsPath( const OUString& rFragmentPath )
54 {
55     sal_Int32 nPathLen = ::std::max< sal_Int32 >( rFragmentPath.lastIndexOf( '/' ) + 1, 0 );
56     return
57         OUStringBuffer( rFragmentPath.copy( 0, nPathLen ) ).    // file path including slash
58         appendAscii( "_rels/" ).                                // additional '_rels/' path
59         append( rFragmentPath.copy( nPathLen ) ).               // file name after path
60         appendAscii( ".rels" ).                                 // '.rels' suffix
61         makeStringAndClear();
62 }
63 
64 } // namespace
65 
66 // ============================================================================
67 
68 RelationsFragment::RelationsFragment( XmlFilterBase& rFilter, RelationsRef xRelations ) :
69     FragmentHandler( rFilter, lclGetRelationsPath( xRelations->getFragmentPath() ), xRelations ),
70     mxRelations( xRelations )
71 {
72 }
73 
74 Reference< XFastContextHandler > RelationsFragment::createFastChildContext(
75         sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
76 {
77     Reference< XFastContextHandler > xRet;
78     AttributeList aAttribs( rxAttribs );
79     switch( nElement )
80     {
81         case PR_TOKEN( Relationship ):
82         {
83             Relation aRelation;
84             aRelation.maId     = aAttribs.getString( XML_Id, OUString() );
85             aRelation.maType   = aAttribs.getString( XML_Type, OUString() );
86             aRelation.maTarget = aAttribs.getString( XML_Target, OUString() );
87             if( (aRelation.maId.getLength() > 0) && (aRelation.maType.getLength() > 0) && (aRelation.maTarget.getLength() > 0) )
88             {
89                 sal_Int32 nTargetMode = aAttribs.getToken( XML_TargetMode, XML_Internal );
90                 OSL_ENSURE( (nTargetMode == XML_Internal) || (nTargetMode == XML_External),
91                     "RelationsFragment::createFastChildContext - unexpected target mode, assuming external" );
92                 aRelation.mbExternal = nTargetMode != XML_Internal;
93 
94                 OSL_ENSURE( mxRelations->count( aRelation.maId ) == 0,
95                     "RelationsFragment::createFastChildContext - relation identifier exists already" );
96                 mxRelations->insert( Relations::value_type( aRelation.maId, aRelation ) );
97             }
98         }
99         break;
100         case PR_TOKEN( Relationships ):
101             xRet = getFastContextHandler();
102         break;
103     }
104     return xRet;
105 }
106 
107 // ============================================================================
108 
109 } // namespace core
110 } // namespace oox
111