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