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_ucb.hxx" 30 31 /************************************************************************** 32 TODO 33 ************************************************************************** 34 35 *************************************************************************/ 36 37 #include "rtl/ustrbuf.hxx" 38 #include "osl/diagnose.h" 39 40 #include "hierarchyuri.hxx" 41 42 using namespace hierarchy_ucp; 43 44 //========================================================================= 45 46 #define DEFAULT_DATA_SOURCE_SERVICE \ 47 "com.sun.star.ucb.DefaultHierarchyDataSource" 48 49 //========================================================================= 50 //========================================================================= 51 // 52 // HierarchyUri Implementation. 53 // 54 //========================================================================= 55 //========================================================================= 56 57 void HierarchyUri::init() const 58 { 59 // Already inited? 60 if ( m_aUri.getLength() && !m_aPath.getLength() ) 61 { 62 // Note: Maybe it's a re-init, setUri only resets m_aPath! 63 m_aService = m_aParentUri = m_aName = rtl::OUString(); 64 65 // URI must match at least: <sheme>: 66 if ( ( m_aUri.getLength() < HIERARCHY_URL_SCHEME_LENGTH + 1 ) ) 67 { 68 // error, but remember that we did a init(). 69 m_aPath = rtl::OUString::createFromAscii( "/" ); 70 return; 71 } 72 73 // Scheme is case insensitive. 74 rtl::OUString aScheme 75 = m_aUri.copy( 0, HIERARCHY_URL_SCHEME_LENGTH ).toAsciiLowerCase(); 76 if ( aScheme.equalsAsciiL( 77 RTL_CONSTASCII_STRINGPARAM( HIERARCHY_URL_SCHEME ) ) ) 78 { 79 m_aUri = m_aUri.replaceAt( 0, aScheme.getLength(), aScheme ); 80 81 sal_Int32 nPos = 0; 82 83 // If the URI has no service specifier, insert default service. 84 // This is for backward compatibility and for convenience. 85 86 if ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 1 ) 87 { 88 // root folder URI without path and service specifier. 89 m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 90 "//" DEFAULT_DATA_SOURCE_SERVICE "/" ) ); 91 m_aService 92 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 93 DEFAULT_DATA_SOURCE_SERVICE ) ); 94 95 nPos = m_aUri.getLength() - 1; 96 } 97 else if ( ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 2 ) 98 && 99 ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 1 ] 100 == sal_Unicode( '/' ) ) ) 101 { 102 // root folder URI without service specifier. 103 m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 104 "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) ); 105 m_aService 106 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 107 DEFAULT_DATA_SOURCE_SERVICE ) ); 108 109 nPos = m_aUri.getLength() - 1; 110 } 111 else if ( ( m_aUri.getLength() > HIERARCHY_URL_SCHEME_LENGTH + 2 ) 112 && 113 ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 2 ] 114 != sal_Unicode( '/' ) ) ) 115 { 116 // other (no root folder) URI without service specifier. 117 m_aUri = m_aUri.replaceAt( 118 HIERARCHY_URL_SCHEME_LENGTH + 2, 119 0, 120 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 121 "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) ) ); 122 m_aService 123 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 124 DEFAULT_DATA_SOURCE_SERVICE ) ); 125 126 nPos 127 = HIERARCHY_URL_SCHEME_LENGTH + 3 + m_aService.getLength(); 128 } 129 else 130 { 131 // URI with service specifier. 132 sal_Int32 nStart = HIERARCHY_URL_SCHEME_LENGTH + 3; 133 134 // Here: - m_aUri has at least the form "<scheme>://" 135 // - nStart points to char after <scheme>:// 136 137 // Only <scheme>:// ? 138 if ( nStart == m_aUri.getLength() ) 139 { 140 // error, but remember that we did a init(). 141 m_aPath = rtl::OUString::createFromAscii( "/" ); 142 return; 143 } 144 145 // Empty path segments? 146 if ( m_aUri.indexOf( 147 rtl::OUString::createFromAscii( "//" ), 148 nStart ) != -1 ) 149 { 150 // error, but remember that we did a init(). 151 m_aPath = rtl::OUString::createFromAscii( "/" ); 152 return; 153 } 154 155 sal_Int32 nEnd = m_aUri.indexOf( '/', nStart ); 156 157 // Only <scheme>:/// ? 158 if ( nEnd == nStart ) 159 { 160 // error, but remember that we did a init(). 161 m_aPath = rtl::OUString::createFromAscii( "/" ); 162 return; 163 } 164 165 if ( nEnd == -1 ) 166 { 167 // Trailing slash missing. 168 nEnd = m_aUri.getLength(); 169 m_aUri += rtl::OUString::createFromAscii( "/" ); 170 } 171 172 m_aService = m_aUri.copy( nStart, nEnd - nStart ); 173 174 nPos = nEnd; 175 } 176 177 // Here: - m_aUri has at least the form "<scheme>://<service>/" 178 // - m_aService was set 179 // - m_aPath, m_aParentPath, m_aName not yet set 180 // - nPos points to slash after service specifier 181 182 // Remove trailing slash, if not a root folder URI. 183 sal_Int32 nEnd = m_aUri.lastIndexOf( '/' ); 184 if ( ( nEnd > nPos ) && ( nEnd == ( m_aUri.getLength() - 1 ) ) ) 185 m_aUri = m_aUri.copy( 0, nEnd ); 186 187 // Path (includes leading slash) 188 m_aPath = m_aUri.copy( nPos ); 189 190 // parent URI + name 191 sal_Int32 nLastSlash = m_aUri.lastIndexOf( '/' ); 192 if ( ( nLastSlash != -1 ) && 193 ( nLastSlash != m_aUri.getLength() - 1 ) ) // root 194 { 195 m_aParentUri = m_aUri.copy( 0, nLastSlash ); 196 m_aName = m_aUri.copy( nLastSlash + 1 ); 197 } 198 199 // success 200 m_bValid = true; 201 } 202 else 203 { 204 // error, but remember that we did a init(). 205 m_aPath = rtl::OUString::createFromAscii( "/" ); 206 } 207 } 208 } 209 210