1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26
27 /**************************************************************************
28 TODO
29 **************************************************************************
30
31 *************************************************************************/
32
33 #include "rtl/ustrbuf.hxx"
34 #include "osl/diagnose.h"
35
36 #include "hierarchyuri.hxx"
37
38 using namespace hierarchy_ucp;
39
40 //=========================================================================
41
42 #define DEFAULT_DATA_SOURCE_SERVICE \
43 "com.sun.star.ucb.DefaultHierarchyDataSource"
44
45 //=========================================================================
46 //=========================================================================
47 //
48 // HierarchyUri Implementation.
49 //
50 //=========================================================================
51 //=========================================================================
52
init() const53 void HierarchyUri::init() const
54 {
55 // Already inited?
56 if ( m_aUri.getLength() && !m_aPath.getLength() )
57 {
58 // Note: Maybe it's a re-init, setUri only resets m_aPath!
59 m_aService = m_aParentUri = m_aName = rtl::OUString();
60
61 // URI must match at least: <sheme>:
62 if ( ( m_aUri.getLength() < HIERARCHY_URL_SCHEME_LENGTH + 1 ) )
63 {
64 // error, but remember that we did a init().
65 m_aPath = rtl::OUString::createFromAscii( "/" );
66 return;
67 }
68
69 // Scheme is case insensitive.
70 rtl::OUString aScheme
71 = m_aUri.copy( 0, HIERARCHY_URL_SCHEME_LENGTH ).toAsciiLowerCase();
72 if ( aScheme.equalsAsciiL(
73 RTL_CONSTASCII_STRINGPARAM( HIERARCHY_URL_SCHEME ) ) )
74 {
75 m_aUri = m_aUri.replaceAt( 0, aScheme.getLength(), aScheme );
76
77 sal_Int32 nPos = 0;
78
79 // If the URI has no service specifier, insert default service.
80 // This is for backward compatibility and for convenience.
81
82 if ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 1 )
83 {
84 // root folder URI without path and service specifier.
85 m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
86 "//" DEFAULT_DATA_SOURCE_SERVICE "/" ) );
87 m_aService
88 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
89 DEFAULT_DATA_SOURCE_SERVICE ) );
90
91 nPos = m_aUri.getLength() - 1;
92 }
93 else if ( ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 2 )
94 &&
95 ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 1 ]
96 == sal_Unicode( '/' ) ) )
97 {
98 // root folder URI without service specifier.
99 m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
100 "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) );
101 m_aService
102 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
103 DEFAULT_DATA_SOURCE_SERVICE ) );
104
105 nPos = m_aUri.getLength() - 1;
106 }
107 else if ( ( m_aUri.getLength() > HIERARCHY_URL_SCHEME_LENGTH + 2 )
108 &&
109 ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 2 ]
110 != sal_Unicode( '/' ) ) )
111 {
112 // other (no root folder) URI without service specifier.
113 m_aUri = m_aUri.replaceAt(
114 HIERARCHY_URL_SCHEME_LENGTH + 2,
115 0,
116 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
117 "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) ) );
118 m_aService
119 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
120 DEFAULT_DATA_SOURCE_SERVICE ) );
121
122 nPos
123 = HIERARCHY_URL_SCHEME_LENGTH + 3 + m_aService.getLength();
124 }
125 else
126 {
127 // URI with service specifier.
128 sal_Int32 nStart = HIERARCHY_URL_SCHEME_LENGTH + 3;
129
130 // Here: - m_aUri has at least the form "<scheme>://"
131 // - nStart points to char after <scheme>://
132
133 // Only <scheme>:// ?
134 if ( nStart == m_aUri.getLength() )
135 {
136 // error, but remember that we did a init().
137 m_aPath = rtl::OUString::createFromAscii( "/" );
138 return;
139 }
140
141 // Empty path segments?
142 if ( m_aUri.indexOf(
143 rtl::OUString::createFromAscii( "//" ),
144 nStart ) != -1 )
145 {
146 // error, but remember that we did a init().
147 m_aPath = rtl::OUString::createFromAscii( "/" );
148 return;
149 }
150
151 sal_Int32 nEnd = m_aUri.indexOf( '/', nStart );
152
153 // Only <scheme>:/// ?
154 if ( nEnd == nStart )
155 {
156 // error, but remember that we did a init().
157 m_aPath = rtl::OUString::createFromAscii( "/" );
158 return;
159 }
160
161 if ( nEnd == -1 )
162 {
163 // Trailing slash missing.
164 nEnd = m_aUri.getLength();
165 m_aUri += rtl::OUString::createFromAscii( "/" );
166 }
167
168 m_aService = m_aUri.copy( nStart, nEnd - nStart );
169
170 nPos = nEnd;
171 }
172
173 // Here: - m_aUri has at least the form "<scheme>://<service>/"
174 // - m_aService was set
175 // - m_aPath, m_aParentPath, m_aName not yet set
176 // - nPos points to slash after service specifier
177
178 // Remove trailing slash, if not a root folder URI.
179 sal_Int32 nEnd = m_aUri.lastIndexOf( '/' );
180 if ( ( nEnd > nPos ) && ( nEnd == ( m_aUri.getLength() - 1 ) ) )
181 m_aUri = m_aUri.copy( 0, nEnd );
182
183 // Path (includes leading slash)
184 m_aPath = m_aUri.copy( nPos );
185
186 // parent URI + name
187 sal_Int32 nLastSlash = m_aUri.lastIndexOf( '/' );
188 if ( ( nLastSlash != -1 ) &&
189 ( nLastSlash != m_aUri.getLength() - 1 ) ) // root
190 {
191 m_aParentUri = m_aUri.copy( 0, nLastSlash );
192 m_aName = m_aUri.copy( nLastSlash + 1 );
193 }
194
195 // success
196 m_bValid = true;
197 }
198 else
199 {
200 // error, but remember that we did a init().
201 m_aPath = rtl::OUString::createFromAscii( "/" );
202 }
203 }
204 }
205
206