bump product version to 6.3.0.0.beta1
[LibreOffice.git] / oox / source / core / relations.cxx
blob49a84d368e567170946446f9b7643aa639dcc199
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <oox/core/relations.hxx>
22 #include <rtl/ustrbuf.hxx>
23 #include <oox/helper/helper.hxx>
25 namespace oox {
26 namespace core {
28 namespace {
30 OUString lclRemoveFileName( const OUString& rPath )
32 return rPath.copy( 0, ::std::max< sal_Int32 >( rPath.lastIndexOf( '/' ), 0 ) );
35 OUString lclAppendFileName( const OUString& rPath, const OUString& rFileName )
37 return rPath.isEmpty() ? rFileName :
38 rPath + OUStringLiteral1('/') + rFileName;
41 OUString createOfficeDocRelationTypeTransitional(const OUString& rType)
43 return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/" + rType;
46 OUString createOfficeDocRelationTypeStrict(const OUString& rType)
48 return "http://purl.oclc.org/ooxml/officeDocument/relationships/" + rType;
53 Relations::Relations( const OUString& rFragmentPath )
54 : maMap()
55 , maFragmentPath( rFragmentPath )
59 const Relation* Relations::getRelationFromRelId( const OUString& rId ) const
61 ::std::map< OUString, Relation >::const_iterator aIt = maMap.find( rId );
62 return (aIt == maMap.end()) ? nullptr : &aIt->second;
65 const Relation* Relations::getRelationFromFirstType( const OUString& rType ) const
67 for (auto const& elem : maMap)
68 if( elem.second.maType.equalsIgnoreAsciiCase( rType ) )
69 return &elem.second;
70 return nullptr;
73 RelationsRef Relations::getRelationsFromTypeFromOfficeDoc( const OUString& rType ) const
75 RelationsRef xRelations( new Relations( maFragmentPath ) );
76 for (auto const& elem : maMap)
77 if( elem.second.maType.equalsIgnoreAsciiCase( createOfficeDocRelationTypeTransitional(rType) ) ||
78 elem.second.maType.equalsIgnoreAsciiCase( createOfficeDocRelationTypeStrict(rType) ))
79 xRelations->maMap[ elem.first ] = elem.second;
80 return xRelations;
83 OUString Relations::getExternalTargetFromRelId( const OUString& rRelId ) const
85 const Relation* pRelation = getRelationFromRelId( rRelId );
86 return (pRelation && pRelation->mbExternal) ? pRelation->maTarget : OUString();
89 OUString Relations::getInternalTargetFromRelId( const OUString& rRelId ) const
91 const Relation* pRelation = getRelationFromRelId( rRelId );
92 return (pRelation && !pRelation->mbExternal) ? pRelation->maTarget : OUString();
95 OUString Relations::getFragmentPathFromRelation( const Relation& rRelation ) const
97 // no target, no fragment path
98 if( rRelation.mbExternal || rRelation.maTarget.isEmpty() )
99 return OUString();
101 // absolute target: return it without leading slash (#i100978)
102 if( rRelation.maTarget[ 0 ] == '/' )
103 return rRelation.maTarget.copy( 1 );
105 // empty fragment path: return target
106 if( maFragmentPath.isEmpty() )
107 return rRelation.maTarget;
109 // resolve relative target path according to base path
110 OUString aPath = lclRemoveFileName( maFragmentPath );
111 sal_Int32 nStartPos = 0;
112 while( nStartPos < rRelation.maTarget.getLength() )
114 sal_Int32 nSepPos = rRelation.maTarget.indexOf( '/', nStartPos );
115 if( nSepPos < 0 ) nSepPos = rRelation.maTarget.getLength();
116 // append next directory name from aTarget to aPath, or remove last directory on '../'
117 if( (nStartPos + 2 == nSepPos) && (rRelation.maTarget[ nStartPos ] == '.') && (rRelation.maTarget[ nStartPos + 1 ] == '.') )
118 aPath = lclRemoveFileName( aPath );
119 else
120 aPath = lclAppendFileName( aPath, rRelation.maTarget.copy( nStartPos, nSepPos - nStartPos ) );
121 // move nStartPos to next directory name
122 nStartPos = nSepPos + 1;
125 return aPath;
128 OUString Relations::getFragmentPathFromRelId( const OUString& rRelId ) const
130 const Relation* pRelation = getRelationFromRelId( rRelId );
131 return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
134 OUString Relations::getFragmentPathFromFirstType( const OUString& rType ) const
136 const Relation* pRelation = getRelationFromFirstType( rType );
137 return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
140 OUString Relations::getFragmentPathFromFirstTypeFromOfficeDoc( const OUString& rType ) const
142 OUString aTransitionalType(createOfficeDocRelationTypeTransitional(rType));
143 const Relation* pRelation = getRelationFromFirstType( aTransitionalType );
144 if(!pRelation)
146 OUString aStrictType = createOfficeDocRelationTypeStrict(rType);
147 pRelation = getRelationFromFirstType( aStrictType );
149 return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
152 } // namespace core
153 } // namespace oox
155 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */