Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "deployment.hrc"
31 : : #include "dp_misc.h"
32 : : #include "dp_ucb.h"
33 : : #include "rtl/uri.hxx"
34 : : #include "rtl/ustrbuf.hxx"
35 : : #include "ucbhelper/content.hxx"
36 : : #include "xmlscript/xml_helper.hxx"
37 : : #include "com/sun/star/io/XInputStream.hpp"
38 : : #include "com/sun/star/ucb/CommandFailedException.hpp"
39 : : #include "com/sun/star/ucb/ContentInfo.hpp"
40 : : #include "com/sun/star/ucb/ContentInfoAttribute.hpp"
41 : :
42 : :
43 : : using namespace ::com::sun::star;
44 : : using namespace ::com::sun::star::uno;
45 : : using namespace ::com::sun::star::ucb;
46 : : using ::rtl::OUString;
47 : :
48 : : namespace dp_misc
49 : : {
50 : :
51 : : //==============================================================================
52 : 14877 : bool create_ucb_content(
53 : : ::ucbhelper::Content * ret_ucbContent, OUString const & url,
54 : : Reference<XCommandEnvironment> const & xCmdEnv,
55 : : bool throw_exc )
56 : : {
57 : : try {
58 : : // Existense check...
59 : : // content ctor/isFolder() will throw exception in case the resource
60 : : // does not exist.
61 : :
62 : : // dilemma: no chance to use the given iahandler here, because it would
63 : : // raise no such file dialogs, else no interaction for
64 : : // passwords, ...? xxx todo
65 : : ::ucbhelper::Content ucbContent(
66 [ + - ]: 14877 : url, Reference<XCommandEnvironment>() );
67 : :
68 [ + + ]: 14877 : ucbContent.isFolder();
69 : :
70 [ + + ]: 9784 : if (ret_ucbContent != 0)
71 : : {
72 [ + - ]: 9412 : ucbContent.setCommandEnvironment( xCmdEnv );
73 [ + - ]: 9412 : *ret_ucbContent = ucbContent;
74 : : }
75 [ + - ]: 19970 : return true;
76 : : }
77 : 0 : catch (const RuntimeException &) {
78 : 0 : throw;
79 : : }
80 [ - - + ]: 10186 : catch (const Exception &) {
81 [ - + ]: 5093 : if (throw_exc)
82 : 0 : throw;
83 : : }
84 : 5093 : return false;
85 : : }
86 : :
87 : : //==============================================================================
88 : 6930 : bool create_folder(
89 : : ::ucbhelper::Content * ret_ucb_content, OUString const & url_,
90 : : Reference<XCommandEnvironment> const & xCmdEnv, bool throw_exc )
91 : : {
92 [ + - ]: 6930 : ::ucbhelper::Content ucb_content;
93 [ + - ][ + + ]: 6930 : if (create_ucb_content(
94 : : &ucb_content, url_, xCmdEnv, false /* no throw */ ))
95 : : {
96 [ + - ][ + - ]: 5230 : if (ucb_content.isFolder()) {
97 [ + + ]: 5230 : if (ret_ucb_content != 0)
98 [ + - ]: 3248 : *ret_ucb_content = ucb_content;
99 : 5230 : return true;
100 : : }
101 : : }
102 : :
103 : 1700 : OUString url( url_ );
104 : : // xxx todo: find parent
105 : 1700 : sal_Int32 slash = url.lastIndexOf( '/' );
106 [ + + ]: 1700 : if (slash < 0) {
107 : : // fallback:
108 [ + - ]: 2 : url = expandUnoRcUrl( url );
109 : 2 : slash = url.lastIndexOf( '/' );
110 : : }
111 [ - + ]: 1700 : if (slash < 0) {
112 : : // invalid: has to be at least "auth:/..."
113 [ # # ]: 0 : if (throw_exc)
114 : : throw ContentCreationException(
115 : : OUSTR("Cannot create folder (invalid path): ") + url,
116 [ # # ][ # # ]: 0 : Reference<XInterface>(), ContentCreationError_UNKNOWN );
117 : 0 : return false;
118 : : }
119 [ + - ]: 1700 : ::ucbhelper::Content parentContent;
120 [ - + ]: 1700 : if (! create_folder(
121 [ + - ]: 1700 : &parentContent, url.copy( 0, slash ), xCmdEnv, throw_exc ))
122 : 0 : return false;
123 : : const Any title( ::rtl::Uri::decode( url.copy( slash + 1 ),
124 : : rtl_UriDecodeWithCharset,
125 [ + - ]: 1700 : RTL_TEXTENCODING_UTF8 ) );
126 : : const Sequence<ContentInfo> infos(
127 [ + - ]: 1700 : parentContent.queryCreatableContentsInfo() );
128 [ + - ]: 3400 : for ( sal_Int32 pos = 0; pos < infos.getLength(); ++pos )
129 : : {
130 : : // look KIND_FOLDER:
131 : 3400 : ContentInfo const & info = infos[ pos ];
132 [ + + ]: 3400 : if ((info.Attributes & ContentInfoAttribute::KIND_FOLDER) != 0)
133 : : {
134 : : // make sure the only required bootstrap property is "Title":
135 : 1700 : Sequence<beans::Property> const & rProps = info.Properties;
136 [ + - ][ - + ]: 1700 : if ( rProps.getLength() != 1 || rProps[ 0 ].Name != "Title" )
[ - + ]
137 : 0 : continue;
138 : :
139 : : try {
140 [ + - ]: 1700 : if (parentContent.insertNewContent(
141 : : info.Type,
142 : : StrTitle::getTitleSequence(),
143 : : Sequence<Any>( &title, 1 ),
144 [ + - ][ + - ]: 1700 : ucb_content )) {
[ + - ][ + - ]
[ + - ]
145 [ + + ]: 1700 : if (ret_ucb_content != 0)
146 [ + - ]: 132 : *ret_ucb_content = ucb_content;
147 : 1700 : return true;
148 : : }
149 : : }
150 : 0 : catch (const RuntimeException &) {
151 : 0 : throw;
152 : : }
153 [ # # ]: 0 : catch (const CommandFailedException &) {
154 : : // Interaction Handler already handled the error
155 : : // that has occurred...
156 : : }
157 [ # # # # : 0 : catch (const Exception &) {
# # ]
158 [ # # ]: 0 : if (throw_exc)
159 : 0 : throw;
160 : 0 : return false;
161 : : }
162 : : }
163 : : }
164 [ # # ]: 0 : if (throw_exc)
165 : : throw ContentCreationException(
166 : : OUSTR("Cannot create folder: ") + url,
167 [ # # ][ # # ]: 0 : Reference<XInterface>(), ContentCreationError_UNKNOWN );
168 [ + - ][ + - ]: 6930 : return false;
[ + - ]
169 : : }
170 : :
171 : : //==============================================================================
172 : 1246 : bool erase_path( OUString const & url,
173 : : Reference<XCommandEnvironment> const & xCmdEnv,
174 : : bool throw_exc )
175 : : {
176 [ + - ]: 1246 : ::ucbhelper::Content ucb_content;
177 [ + - ][ + + ]: 1246 : if (create_ucb_content( &ucb_content, url, xCmdEnv, false /* no throw */ ))
178 : : {
179 : : try {
180 : : ucb_content.executeCommand(
181 [ + - ][ + - ]: 4 : OUSTR("delete"), Any( true /* delete physically */ ) );
[ + - ]
182 : : }
183 : 0 : catch (const RuntimeException &) {
184 : 0 : throw;
185 : : }
186 [ # # # # : 0 : catch (const Exception &) {
# ]
187 [ # # ]: 0 : if (throw_exc)
188 : 0 : throw;
189 : 0 : return false;
190 : : }
191 : : }
192 [ + - ]: 1246 : return true;
193 : : }
194 : :
195 : : //==============================================================================
196 : 2172 : ::rtl::ByteSequence readFile( ::ucbhelper::Content & ucb_content )
197 : : {
198 : 2172 : ::rtl::ByteSequence bytes;
199 : : Reference<io::XOutputStream> xStream(
200 [ + - ]: 2172 : ::xmlscript::createOutputStream( &bytes ) );
201 [ + - ][ - + ]: 2172 : if (! ucb_content.openStream( xStream ))
202 : : throw RuntimeException(
203 : : OUSTR(
204 : : "::ucbhelper::Content::openStream( XOutputStream ) failed!"),
205 [ # # ][ # # ]: 0 : 0 );
[ # # ]
206 : 2172 : return bytes;
207 : : }
208 : :
209 : : //==============================================================================
210 : 374 : bool readLine( OUString * res, OUString const & startingWith,
211 : : ::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc )
212 : : {
213 : : // read whole file:
214 [ + - ]: 374 : ::rtl::ByteSequence bytes( readFile( ucb_content ) );
215 : 374 : OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
216 [ + - ]: 748 : bytes.getLength(), textenc );
217 : 374 : sal_Int32 pos = 0;
218 : 570 : for (;;)
219 : : {
220 [ + + ]: 944 : if (file.match( startingWith, pos ))
221 : : {
222 : 248 : ::rtl::OUStringBuffer buf;
223 : 248 : sal_Int32 start = pos;
224 : 248 : pos += startingWith.getLength();
225 : 0 : for (;;)
226 : : {
227 : 248 : pos = file.indexOf( LF, pos );
228 [ - + ]: 248 : if (pos < 0) { // EOF
229 [ # # ]: 0 : buf.append( file.copy( start ) );
230 : : }
231 : : else
232 : : {
233 [ + - ][ - + ]: 248 : if (pos > 0 && file[ pos - 1 ] == CR)
[ - + ]
234 : : {
235 : : // consume extra CR
236 [ # # ]: 0 : buf.append( file.copy( start, pos - start - 1 ) );
237 : 0 : ++pos;
238 : : }
239 : : else
240 [ + - ]: 248 : buf.append( file.copy( start, pos - start ) );
241 : 248 : ++pos; // consume LF
242 : : // check next line:
243 [ + + + - : 496 : if (pos < file.getLength() &&
- + ][ - + ]
244 : 248 : (file[ pos ] == ' ' || file[ pos ] == '\t'))
245 : : {
246 [ # # ]: 0 : buf.append( static_cast<sal_Unicode>(' ') );
247 : 0 : ++pos;
248 : 0 : start = pos;
249 : 0 : continue;
250 : : }
251 : : }
252 : 248 : break;
253 : : }
254 [ + - ]: 248 : *res = buf.makeStringAndClear();
255 : 248 : return true;
256 : : }
257 : : // next line:
258 : 696 : sal_Int32 next_lf = file.indexOf( LF, pos );
259 [ + + ]: 696 : if (next_lf < 0) // EOF
260 : 126 : break;
261 : 570 : pos = next_lf + 1;
262 : : }
263 : 374 : return false;
264 : : }
265 : :
266 : 0 : bool readProperties( ::std::list< ::std::pair< ::rtl::OUString, ::rtl::OUString> > & out_result,
267 : : ::ucbhelper::Content & ucb_content )
268 : : {
269 : : // read whole file:
270 [ # # ]: 0 : ::rtl::ByteSequence bytes( readFile( ucb_content ) );
271 : 0 : OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
272 [ # # ]: 0 : bytes.getLength(), RTL_TEXTENCODING_UTF8);
273 : 0 : sal_Int32 pos = 0;
274 : :
275 : 0 : for (;;)
276 : : {
277 : :
278 : 0 : ::rtl::OUStringBuffer buf;
279 : 0 : sal_Int32 start = pos;
280 : :
281 : 0 : bool bEOF = false;
282 : 0 : pos = file.indexOf( LF, pos );
283 [ # # ]: 0 : if (pos < 0) { // EOF
284 [ # # ]: 0 : buf.append( file.copy( start ) );
285 : 0 : bEOF = true;
286 : : }
287 : : else
288 : : {
289 [ # # ][ # # ]: 0 : if (pos > 0 && file[ pos - 1 ] == CR)
[ # # ]
290 : : // consume extra CR
291 [ # # ]: 0 : buf.append( file.copy( start, pos - start - 1 ) );
292 : : else
293 [ # # ]: 0 : buf.append( file.copy( start, pos - start ) );
294 : 0 : pos++;
295 : : }
296 [ # # ]: 0 : OUString aLine = buf.makeStringAndClear();
297 : :
298 : 0 : sal_Int32 posEqual = aLine.indexOf('=');
299 [ # # ][ # # ]: 0 : if (posEqual > 0 && (posEqual + 1) < aLine.getLength())
[ # # ]
300 : : {
301 : 0 : OUString name = aLine.copy(0, posEqual);
302 : 0 : OUString value = aLine.copy(posEqual + 1);
303 [ # # ]: 0 : out_result.push_back(::std::make_pair(name, value));
304 : : }
305 : :
306 [ # # ]: 0 : if (bEOF)
307 : : break;
308 [ # # ][ # # ]: 0 : }
309 : 0 : return false;
310 : : }
311 : :
312 : : }
313 : :
314 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|