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 $
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
;
41 // ============================================================================
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();
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
)
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
;
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) )
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
);
125 aPath
= lclAppendFileName( aPath
, rRelation
.maTarget
.copy( nStartPos
, nSepPos
- nStartPos
) );
126 // move nStartPos to next directory name
127 nStartPos
= nSepPos
+ 1;
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 // ============================================================================