Update ooo320-m1
[ooovba.git] / oox / source / core / relations.cxx
blob12f880f9f7f7328d31c8cecfb1dc81cd4441efd0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: relations.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/core/relations.hxx"
32 #include <rtl/ustrbuf.hxx>
33 #include "oox/helper/helper.hxx"
35 using ::rtl::OUString;
36 using ::rtl::OUStringBuffer;
38 namespace oox {
39 namespace core {
41 // ============================================================================
43 namespace {
45 OUString lclRemoveFileName( const OUString& rPath )
47 return rPath.copy( 0, ::std::max< sal_Int32 >( rPath.lastIndexOf( '/' ), 0 ) );
50 OUString lclAppendFileName( const OUString& rPath, const OUString& rFileName )
52 return (rPath.getLength() == 0) ? rFileName :
53 OUStringBuffer( rPath ).append( sal_Unicode( '/' ) ).append( rFileName ).makeStringAndClear();
56 } // namespace
58 // ============================================================================
60 Relations::Relations( const OUString& rFragmentPath ) :
61 maFragmentPath( rFragmentPath )
65 const Relation* Relations::getRelationFromRelId( const OUString& rId ) const
67 const_iterator aIt = find( rId );
68 return (aIt == end()) ? 0 : &aIt->second;
71 const Relation* Relations::getRelationFromFirstType( const OUString& rType ) const
73 for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
74 if( aIt->second.maType == rType )
75 return &aIt->second;
76 return 0;
79 RelationsRef Relations::getRelationsFromType( const OUString& rType ) const
81 RelationsRef xRelations( new Relations( maFragmentPath ) );
82 for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
83 if( aIt->second.maType == rType )
84 (*xRelations)[ aIt->first ] = aIt->second;
85 return xRelations;
88 OUString Relations::getExternalTargetFromRelId( const OUString& rRelId ) const
90 const Relation* pRelation = getRelationFromRelId( rRelId );
91 return (pRelation && pRelation->mbExternal) ? pRelation->maTarget : OUString();
94 OUString Relations::getExternalTargetFromFirstType( const OUString& rType ) const
96 const Relation* pRelation = getRelationFromFirstType( rType );
97 return (pRelation && pRelation->mbExternal) ? pRelation->maTarget : OUString();
100 OUString Relations::getFragmentPathFromRelation( const Relation& rRelation ) const
102 // no target, no fragment path
103 if( rRelation.mbExternal || (rRelation.maTarget.getLength() == 0) )
104 return OUString();
106 // absolute target: return it without leading slash (#i100978)
107 if( rRelation.maTarget[ 0 ] == '/' )
108 return rRelation.maTarget.copy( 1 );
110 // empty fragment path: return target
111 if( maFragmentPath.getLength() == 0 )
112 return rRelation.maTarget;
114 // resolve relative target path according to base path
115 OUString aPath = lclRemoveFileName( maFragmentPath );
116 sal_Int32 nStartPos = 0;
117 while( nStartPos < rRelation.maTarget.getLength() )
119 sal_Int32 nSepPos = rRelation.maTarget.indexOf( '/', nStartPos );
120 if( nSepPos < 0 ) nSepPos = rRelation.maTarget.getLength();
121 // append next directory name from aTarget to aPath, or remove last directory on '../'
122 if( (nStartPos + 2 == nSepPos) && (rRelation.maTarget[ nStartPos ] == '.') && (rRelation.maTarget[ nStartPos + 1 ] == '.') )
123 aPath = lclRemoveFileName( aPath );
124 else
125 aPath = lclAppendFileName( aPath, rRelation.maTarget.copy( nStartPos, nSepPos - nStartPos ) );
126 // move nStartPos to next directory name
127 nStartPos = nSepPos + 1;
130 return aPath;
133 OUString Relations::getFragmentPathFromRelId( const OUString& rRelId ) const
135 const Relation* pRelation = getRelationFromRelId( rRelId );
136 return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
139 OUString Relations::getFragmentPathFromFirstType( const OUString& rType ) const
141 const Relation* pRelation = getRelationFromFirstType( rType );
142 return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
145 // ============================================================================
147 } // namespace core
148 } // namespace oox