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_desktop.hxx"
26
27 #include "dp_misc.h"
28 #include "rtl/strbuf.hxx"
29 #include "osl/time.h"
30 #include "osl/thread.h"
31 #include "cppuhelper/compbase1.hxx"
32 #include "comphelper/anytostring.hxx"
33 #include "comphelper/servicedecl.hxx"
34 #include "comphelper/unwrapargs.hxx"
35 #include "com/sun/star/deployment/DeploymentException.hpp"
36 #include "com/sun/star/ucb/XProgressHandler.hpp"
37 #include "com/sun/star/ucb/XSimpleFileAccess.hpp"
38 #include "com/sun/star/io/XSeekable.hpp"
39 #include <stdio.h>
40
41
42 using namespace ::rtl;
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
45
46 namespace dp_log {
47
48 typedef ::cppu::WeakComponentImplHelper1<ucb::XProgressHandler> t_log_helper;
49
50 //==============================================================================
51 class ProgressLogImpl : public ::dp_misc::MutexHolder, public t_log_helper
52 {
53 Reference<io::XOutputStream> m_xLogFile;
54 sal_Int32 m_log_level;
55 void log_write( OString const & text );
56
57 protected:
58 virtual void SAL_CALL disposing();
59 virtual ~ProgressLogImpl();
60
61 public:
62 ProgressLogImpl( Sequence<Any> const & args,
63 Reference<XComponentContext> const & xContext );
64
65 // XProgressHandler
66 virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
67 virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
68 virtual void SAL_CALL pop() throw (RuntimeException);
69 };
70
71 //______________________________________________________________________________
~ProgressLogImpl()72 ProgressLogImpl::~ProgressLogImpl()
73 {
74 }
75
76 //______________________________________________________________________________
disposing()77 void ProgressLogImpl::disposing()
78 {
79 try {
80 if (m_xLogFile.is()) {
81 m_xLogFile->closeOutput();
82 m_xLogFile.clear();
83 }
84 }
85 catch (Exception & exc) {
86 (void) exc;
87 OSL_ENSURE( 0, OUStringToOString(
88 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
89 }
90 }
91
92 //______________________________________________________________________________
ProgressLogImpl(Sequence<Any> const & args,Reference<XComponentContext> const & xContext)93 ProgressLogImpl::ProgressLogImpl(
94 Sequence<Any> const & args,
95 Reference<XComponentContext> const & xContext )
96 : t_log_helper( getMutex() ),
97 m_log_level( 0 )
98 {
99 OUString log_file;
100 boost::optional< Reference<task::XInteractionHandler> > interactionHandler;
101 comphelper::unwrapArgs( args, log_file, interactionHandler );
102
103 Reference<ucb::XSimpleFileAccess> xSimpleFileAccess(
104 xContext->getServiceManager()->createInstanceWithContext(
105 OUSTR("com.sun.star.ucb.SimpleFileAccess"),
106 xContext ), UNO_QUERY_THROW );
107 // optional ia handler:
108 if (interactionHandler)
109 xSimpleFileAccess->setInteractionHandler( *interactionHandler );
110
111 m_xLogFile.set(
112 xSimpleFileAccess->openFileWrite( log_file ), UNO_QUERY_THROW );
113 Reference<io::XSeekable> xSeekable( m_xLogFile, UNO_QUERY_THROW );
114 xSeekable->seek( xSeekable->getLength() );
115
116 // write log stamp
117 OStringBuffer buf;
118 buf.append(
119 RTL_CONSTASCII_STRINGPARAM("###### Progress log entry ") );
120 TimeValue m_start_time, tLocal;
121 oslDateTime date_time;
122 if (osl_getSystemTime( &m_start_time ) &&
123 osl_getLocalTimeFromSystemTime( &m_start_time, &tLocal ) &&
124 osl_getDateTimeFromTimeValue( &tLocal, &date_time ))
125 {
126 char ar[ 128 ];
127 snprintf(
128 ar, sizeof (ar),
129 "%04d-%02d-%02d %02d:%02d:%02d ",
130 date_time.Year, date_time.Month, date_time.Day,
131 date_time.Hours, date_time.Minutes, date_time.Seconds );
132 buf.append( ar );
133 }
134 buf.append( RTL_CONSTASCII_STRINGPARAM("######\n") );
135 log_write( buf.makeStringAndClear() );
136 }
137
138 //______________________________________________________________________________
log_write(OString const & text)139 void ProgressLogImpl::log_write( OString const & text )
140 {
141 try {
142 if (m_xLogFile.is()) {
143 m_xLogFile->writeBytes(
144 Sequence< sal_Int8 >(
145 reinterpret_cast< sal_Int8 const * >(text.getStr()),
146 text.getLength() ) );
147 }
148 }
149 catch (io::IOException & exc) {
150 (void) exc;
151 OSL_ENSURE( 0, OUStringToOString(
152 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
153 }
154 }
155
156 // XProgressHandler
157 //______________________________________________________________________________
push(Any const & Status)158 void ProgressLogImpl::push( Any const & Status )
159 throw (RuntimeException)
160 {
161 update( Status );
162 OSL_ASSERT( m_log_level >= 0 );
163 ++m_log_level;
164 }
165
166 //______________________________________________________________________________
update(Any const & Status)167 void ProgressLogImpl::update( Any const & Status )
168 throw (RuntimeException)
169 {
170 if (! Status.hasValue())
171 return;
172
173 OUStringBuffer buf;
174 OSL_ASSERT( m_log_level >= 0 );
175 for ( sal_Int32 n = 0; n < m_log_level; ++n )
176 buf.append( static_cast<sal_Unicode>(' ') );
177
178 OUString msg;
179 if (Status >>= msg) {
180 buf.append( msg );
181 }
182 else {
183 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("ERROR: ") );
184 buf.append( ::comphelper::anyToString(Status) );
185 }
186 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\n") );
187 log_write( OUStringToOString(
188 buf.makeStringAndClear(), osl_getThreadTextEncoding() ) );
189 }
190
191 //______________________________________________________________________________
pop()192 void ProgressLogImpl::pop() throw (RuntimeException)
193 {
194 OSL_ASSERT( m_log_level > 0 );
195 --m_log_level;
196 }
197
198 namespace sdecl = comphelper::service_decl;
199 sdecl::class_<ProgressLogImpl, sdecl::with_args<true> > servicePLI;
200 extern sdecl::ServiceDecl const serviceDecl(
201 servicePLI,
202 // a private one:
203 "com.sun.star.comp.deployment.ProgressLog",
204 "com.sun.star.comp.deployment.ProgressLog" );
205
206 } // namespace dp_log
207
208