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_stoc.hxx"
30 
31 #include "UriReference.hxx"
32 
33 #include "osl/diagnose.h"
34 #include "osl/mutex.hxx"
35 #include "rtl/string.h"
36 #include "rtl/ustrbuf.hxx"
37 #include "rtl/ustring.hxx"
38 #include "sal/types.h"
39 
40 namespace css = com::sun::star;
41 using stoc::uriproc::UriReference;
42 
43 UriReference::UriReference(
44     rtl::OUString const & scheme, bool bIsHierarchical, bool bHasAuthority,
45     rtl::OUString const & authority, rtl::OUString const & path,
46     bool bHasQuery, rtl::OUString const & query):
47     m_scheme(scheme),
48     m_authority(authority),
49     m_path(path),
50     m_query(query),
51     m_isHierarchical(bIsHierarchical),
52     m_hasAuthority(bHasAuthority),
53     m_hasQuery(bHasQuery),
54     m_hasFragment(false)
55 {
56     OSL_ASSERT(scheme.getLength() != 0 || bIsHierarchical);
57     OSL_ASSERT(!bHasAuthority || bIsHierarchical);
58     OSL_ASSERT(authority.getLength() == 0 || bHasAuthority);
59     OSL_ASSERT(!bHasQuery || bIsHierarchical);
60     OSL_ASSERT(query.getLength() == 0 || bHasQuery);
61 }
62 
63 UriReference::~UriReference() {}
64 
65 rtl::OUString UriReference::getUriReference() throw (css::uno::RuntimeException)
66 {
67     osl::MutexGuard g(m_mutex);
68     rtl::OUStringBuffer buf;
69     if (m_scheme.getLength() != 0) {
70         buf.append(m_scheme);
71         buf.append(static_cast< sal_Unicode >(':'));
72     }
73     appendSchemeSpecificPart(buf);
74     if (m_hasFragment) {
75         buf.append(static_cast< sal_Unicode >('#'));
76         buf.append(m_fragment);
77     }
78     return buf.makeStringAndClear();
79 }
80 
81 sal_Bool UriReference::isAbsolute() throw (css::uno::RuntimeException) {
82     return m_scheme.getLength() != 0;
83 }
84 
85 rtl::OUString UriReference::getScheme() throw (css::uno::RuntimeException) {
86     return m_scheme;
87 }
88 
89 rtl::OUString UriReference::getSchemeSpecificPart()
90     throw (css::uno::RuntimeException)
91 {
92     osl::MutexGuard g(m_mutex);
93     rtl::OUStringBuffer buf;
94     appendSchemeSpecificPart(buf);
95     return buf.makeStringAndClear();
96 }
97 
98 sal_Bool UriReference::isHierarchical() throw (css::uno::RuntimeException) {
99     osl::MutexGuard g(m_mutex);
100     return m_isHierarchical;
101 }
102 
103 sal_Bool UriReference::hasAuthority() throw (css::uno::RuntimeException) {
104     osl::MutexGuard g(m_mutex);
105     return m_hasAuthority;
106 }
107 
108 rtl::OUString UriReference::getAuthority() throw (css::uno::RuntimeException) {
109     osl::MutexGuard g(m_mutex);
110     return m_authority;
111 }
112 
113 rtl::OUString UriReference::getPath() throw (css::uno::RuntimeException) {
114     osl::MutexGuard g(m_mutex);
115     return m_path;
116 }
117 
118 sal_Bool UriReference::hasRelativePath() throw (css::uno::RuntimeException) {
119     osl::MutexGuard g(m_mutex);
120     return m_isHierarchical && !m_hasAuthority
121         && (m_path.getLength() == 0 || m_path[0] != '/');
122 }
123 
124 sal_Int32 UriReference::getPathSegmentCount() throw (css::uno::RuntimeException)
125 {
126     osl::MutexGuard g(m_mutex);
127     if (!m_isHierarchical || m_path.getLength() == 0) {
128         return 0;
129     } else {
130         sal_Int32 n = m_path[0] == '/' ? 0 : 1;
131         for (sal_Int32 i = 0;; ++i) {
132             i = m_path.indexOf('/', i);
133             if (i < 0) {
134                 break;
135             }
136             ++n;
137         }
138         return n;
139     }
140 }
141 
142 rtl::OUString UriReference::getPathSegment(sal_Int32 index)
143     throw (css::uno::RuntimeException)
144 {
145     osl::MutexGuard g(m_mutex);
146     if (m_isHierarchical && m_path.getLength() != 0 && index >= 0) {
147         for (sal_Int32 i = m_path[0] == '/' ? 1 : 0;; ++i) {
148             if (index-- == 0) {
149                 sal_Int32 j = m_path.indexOf('/', i);
150                 return j < 0 ? m_path.copy(i) : m_path.copy(i, j - i);
151             }
152             i = m_path.indexOf('/', i);
153             if (i < 0) {
154                 break;
155             }
156         }
157     }
158     return rtl::OUString();
159 }
160 
161 sal_Bool UriReference::hasQuery() throw (css::uno::RuntimeException) {
162     osl::MutexGuard g(m_mutex);
163     return m_hasQuery;
164 }
165 
166 rtl::OUString UriReference::getQuery() throw (css::uno::RuntimeException) {
167     osl::MutexGuard g(m_mutex);
168     return m_query;
169 }
170 
171 sal_Bool UriReference::hasFragment() throw (css::uno::RuntimeException) {
172     osl::MutexGuard g(m_mutex);
173     return m_hasFragment;
174 }
175 
176 rtl::OUString UriReference::getFragment() throw (css::uno::RuntimeException) {
177     osl::MutexGuard g(m_mutex);
178     return m_fragment;
179 }
180 
181 void UriReference::setFragment(rtl::OUString const & fragment)
182     throw (css::uno::RuntimeException)
183 {
184     osl::MutexGuard g(m_mutex);
185     m_hasFragment = true;
186     m_fragment = fragment;
187 }
188 
189 void UriReference::clearFragment() throw (css::uno::RuntimeException) {
190     osl::MutexGuard g(m_mutex);
191     m_hasFragment = false;
192     m_fragment = rtl::OUString();
193 }
194 
195 void UriReference::appendSchemeSpecificPart(rtl::OUStringBuffer & buffer) const
196 {
197     if (m_hasAuthority) {
198         buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
199         buffer.append(m_authority);
200     }
201     buffer.append(m_path);
202     if (m_hasQuery) {
203         buffer.append(static_cast< sal_Unicode >('?'));
204         buffer.append(m_query);
205     }
206 }
207