bump product version to 4.1.6.2
[LibreOffice.git] / desktop / source / deployment / misc / dp_ucb.cxx
blob2fff496c5a1a9ea933ddfe797add8e0b383fc2d2
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 .
21 #include "deployment.hrc"
22 #include "dp_misc.h"
23 #include "dp_ucb.h"
24 #include "rtl/uri.hxx"
25 #include "rtl/ustrbuf.hxx"
26 #include "ucbhelper/content.hxx"
27 #include "xmlscript/xml_helper.hxx"
28 #include "com/sun/star/io/XInputStream.hpp"
29 #include "com/sun/star/ucb/CommandFailedException.hpp"
30 #include "com/sun/star/ucb/ContentInfo.hpp"
31 #include "com/sun/star/ucb/ContentInfoAttribute.hpp"
32 #include "comphelper/processfactory.hxx"
34 using namespace ::com::sun::star;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::ucb;
38 namespace dp_misc
41 //==============================================================================
42 bool create_ucb_content(
43 ::ucbhelper::Content * ret_ucbContent, OUString const & url,
44 Reference<XCommandEnvironment> const & xCmdEnv,
45 bool throw_exc )
47 try {
48 // Existense check...
49 // content ctor/isFolder() will throw exception in case the resource
50 // does not exist.
52 // dilemma: no chance to use the given iahandler here, because it would
53 // raise no such file dialogs, else no interaction for
54 // passwords, ...? xxx todo
55 ::ucbhelper::Content ucbContent(
56 url, Reference<XCommandEnvironment>(),
57 comphelper::getProcessComponentContext() );
59 ucbContent.isFolder();
61 if (ret_ucbContent != 0)
63 ucbContent.setCommandEnvironment( xCmdEnv );
64 *ret_ucbContent = ucbContent;
66 return true;
68 catch (const RuntimeException &) {
69 throw;
71 catch (const Exception &) {
72 if (throw_exc)
73 throw;
75 return false;
78 //==============================================================================
79 bool create_folder(
80 ::ucbhelper::Content * ret_ucb_content, OUString const & url_,
81 Reference<XCommandEnvironment> const & xCmdEnv, bool throw_exc )
83 ::ucbhelper::Content ucb_content;
84 if (create_ucb_content(
85 &ucb_content, url_, xCmdEnv, false /* no throw */ ))
87 if (ucb_content.isFolder()) {
88 if (ret_ucb_content != 0)
89 *ret_ucb_content = ucb_content;
90 return true;
94 OUString url( url_ );
95 // xxx todo: find parent
96 sal_Int32 slash = url.lastIndexOf( '/' );
97 if (slash < 0) {
98 // fallback:
99 url = expandUnoRcUrl( url );
100 slash = url.lastIndexOf( '/' );
102 if (slash < 0) {
103 // invalid: has to be at least "auth:/..."
104 if (throw_exc)
105 throw ContentCreationException(
106 "Cannot create folder (invalid path): " + url,
107 Reference<XInterface>(), ContentCreationError_UNKNOWN );
108 return false;
110 ::ucbhelper::Content parentContent;
111 if (! create_folder(
112 &parentContent, url.copy( 0, slash ), xCmdEnv, throw_exc ))
113 return false;
114 const Any title( ::rtl::Uri::decode( url.copy( slash + 1 ),
115 rtl_UriDecodeWithCharset,
116 RTL_TEXTENCODING_UTF8 ) );
117 const Sequence<ContentInfo> infos(
118 parentContent.queryCreatableContentsInfo() );
119 for ( sal_Int32 pos = 0; pos < infos.getLength(); ++pos )
121 // look KIND_FOLDER:
122 ContentInfo const & info = infos[ pos ];
123 if ((info.Attributes & ContentInfoAttribute::KIND_FOLDER) != 0)
125 // make sure the only required bootstrap property is "Title":
126 Sequence<beans::Property> const & rProps = info.Properties;
127 if ( rProps.getLength() != 1 || rProps[ 0 ].Name != "Title" )
128 continue;
130 try {
131 if (parentContent.insertNewContent(
132 info.Type,
133 StrTitle::getTitleSequence(),
134 Sequence<Any>( &title, 1 ),
135 ucb_content )) {
136 if (ret_ucb_content != 0)
137 *ret_ucb_content = ucb_content;
138 return true;
141 catch (const RuntimeException &) {
142 throw;
144 catch (const CommandFailedException &) {
145 // Interaction Handler already handled the error
146 // that has occurred...
148 catch (const Exception &) {
149 if (throw_exc)
150 throw;
151 return false;
155 if (throw_exc)
156 throw ContentCreationException(
157 "Cannot create folder: " + url,
158 Reference<XInterface>(), ContentCreationError_UNKNOWN );
159 return false;
162 //==============================================================================
163 bool erase_path( OUString const & url,
164 Reference<XCommandEnvironment> const & xCmdEnv,
165 bool throw_exc )
167 ::ucbhelper::Content ucb_content;
168 if (create_ucb_content( &ucb_content, url, xCmdEnv, false /* no throw */ ))
170 try {
171 ucb_content.executeCommand(
172 "delete", Any( true /* delete physically */ ) );
174 catch (const RuntimeException &) {
175 throw;
177 catch (const Exception &) {
178 if (throw_exc)
179 throw;
180 return false;
183 return true;
186 //==============================================================================
187 ::rtl::ByteSequence readFile( ::ucbhelper::Content & ucb_content )
189 ::rtl::ByteSequence bytes;
190 Reference<io::XOutputStream> xStream(
191 ::xmlscript::createOutputStream( &bytes ) );
192 if (! ucb_content.openStream( xStream ))
193 throw RuntimeException(
194 "::ucbhelper::Content::openStream( XOutputStream ) failed!",
195 0 );
196 return bytes;
199 //==============================================================================
200 bool readLine( OUString * res, OUString const & startingWith,
201 ::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc )
203 // read whole file:
204 ::rtl::ByteSequence bytes( readFile( ucb_content ) );
205 OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
206 bytes.getLength(), textenc );
207 sal_Int32 pos = 0;
208 for (;;)
210 if (file.match( startingWith, pos ))
212 OUStringBuffer buf;
213 sal_Int32 start = pos;
214 pos += startingWith.getLength();
215 for (;;)
217 pos = file.indexOf( LF, pos );
218 if (pos < 0) { // EOF
219 buf.append( file.copy( start ) );
221 else
223 if (pos > 0 && file[ pos - 1 ] == CR)
225 // consume extra CR
226 buf.append( file.copy( start, pos - start - 1 ) );
227 ++pos;
229 else
230 buf.append( file.copy( start, pos - start ) );
231 ++pos; // consume LF
232 // check next line:
233 if (pos < file.getLength() &&
234 (file[ pos ] == ' ' || file[ pos ] == '\t'))
236 buf.append( static_cast<sal_Unicode>(' ') );
237 ++pos;
238 start = pos;
239 continue;
242 break;
244 *res = buf.makeStringAndClear();
245 return true;
247 // next line:
248 sal_Int32 next_lf = file.indexOf( LF, pos );
249 if (next_lf < 0) // EOF
250 break;
251 pos = next_lf + 1;
253 return false;
256 bool readProperties( ::std::list< ::std::pair< OUString, OUString> > & out_result,
257 ::ucbhelper::Content & ucb_content )
259 // read whole file:
260 ::rtl::ByteSequence bytes( readFile( ucb_content ) );
261 OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
262 bytes.getLength(), RTL_TEXTENCODING_UTF8);
263 sal_Int32 pos = 0;
265 for (;;)
268 OUStringBuffer buf;
269 sal_Int32 start = pos;
271 bool bEOF = false;
272 pos = file.indexOf( LF, pos );
273 if (pos < 0) { // EOF
274 buf.append( file.copy( start ) );
275 bEOF = true;
277 else
279 if (pos > 0 && file[ pos - 1 ] == CR)
280 // consume extra CR
281 buf.append( file.copy( start, pos - start - 1 ) );
282 else
283 buf.append( file.copy( start, pos - start ) );
284 pos++;
286 OUString aLine = buf.makeStringAndClear();
288 sal_Int32 posEqual = aLine.indexOf('=');
289 if (posEqual > 0 && (posEqual + 1) < aLine.getLength())
291 OUString name = aLine.copy(0, posEqual);
292 OUString value = aLine.copy(posEqual + 1);
293 out_result.push_back(::std::make_pair(name, value));
296 if (bEOF)
297 break;
299 return false;
304 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */