incubator-ooo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ksch...@apache.org
Subject svn commit: r1206895 [2/12] - in /incubator/ooo/ooo-site/trunk/content/udk/common: ./ man/ man/concept/ man/draft/ man/draft/scripting/ man/draft/scripting/DesignDoc/ man/images/ man/spec/ man/tasks/ man/tutorial/
Date Sun, 27 Nov 2011 22:50:08 GMT
Added: incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/streams.html
URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/streams.html?rev=1206895&view=auto
==============================================================================
--- incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/streams.html (added)
+++ incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/streams.html Sun Nov 27 22:49:46 2011
@@ -0,0 +1,772 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<HTML>
+<HEAD>
+   <title>Streaming interfaces</title>
+<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
+<style type="text/css">
+	<!--
+h1 { text-align:center; margin-top: 0.2cm; text-decoration: none; color: #ffffff; font-size: 6; margin-top: 0.2cm}
+h2 { margin-top: 0.2cm; margin-bottom=0.1cm; color: #ffffff;
+     background-color: #666699 }
+div li {margin-bottom: 0cm;}
+li {margin-bottom: 0.2cm;}
+dl {margin-bottom: 0.2cm;}
+dd {margin-bottom: 0.2cm;}
+dt {margin-bottom: 0.2cm;}
+-->
+</style>
+</head>
+<BODY>
+<table width=100% border=0 cellpadding=4 cellspacing=0 bgcolor="#666699"
+    summary=Header>
+ <tr>
+  <td>
+      <h1> Streaming interfaces </h1>
+  </td><td>	  
+	  <a href="http://www.openoffice.org/"><IMG SRC="../../../images/open_office_org_logo.gif" ALT="OpenOffice.org" align=right width=109 height=54 border=0/></a>
+  </td>
+ </tr>
+</table>
+
+
+<!-- ************************ A B S T R A C T *************************************** -->
+<h2 id="abstract"> Abstract </h2>
+
+<p>This draft introduces the streaming interfaces (package
+  com.sun.star.uno.io) and gives some examples about how they can be
+  used.</p>
+
+  <p><font size=-1>
+  <u>Note</u>: In some pictures there is a ignoreable 2 in the
+  interface names (e.g. XInputStream2).</font></p>
+
+<!-- ************************ C O N T E N T *************************************** -->
+<h2 id="contents"> Contents </h2>
+<blockquote>
+<a href="#introduction">Introduction</a><br/>
+<a href="#the_interfaces">The interfaces</a><br/>
+<div>
+<ul class=compact>
+	<li>The 1st level : XInputStream/XOutputStream
+	<li>The 2nd level : XActiveDataSink/XActiveDataSource
+	<li>Chaining
+	<li>Piping
+	<li>The 3rd level : XActiveDataControl
+	<li>The 4th level : XConnectable
+	<li>Errorhandling
+</ul>
+</div>
+<p><a href="#standard_services">Standard services</a></p>
+</blockquote>
+
+<!-- ************************ I N T R O D U C T I O N *************************************** -->
+<h2 id=introduction> Introduction </h2>
+
+<DL>
+	<DT>
+	This chapter introduces some notions that you will come across
+	later in this document.</DT>
+
+	<DT>
+	A <B>datasource</B> is an object, that has some data. A <B>datasink</B>
+	is an object that gets some data. Note that no assumption is made
+	about how data is transfered, only the direction of dataflow is
+	fixed (Fig 1.). Note also, that one object can be datasource and
+	datasink at the same time, for example a filter receives data from
+	somewhere (=sink), modifies this data, and broadcasts this data again
+	(=source).</DT>
+	<DT>
+	<IMG SRC="../images/stream_source_sink.gif" NAME="Rahmen1" ALT="Rahmen1" WIDTH=298 HEIGHT=164 BORDER=0/>
+	</DT><DT>
+	Datasources and datasinks can be <B>active</B> or
+	<B>passive</B>.
+	</DT>
+	<DT>
+	1) A <B><I>datasink</I></B> is <B><I>active</I></B>
+	when in the thread of execution the datasink calls a method of
+	datasource to get some data. In this case, the <B><I>datasource </I></B>is
+	<B><I>passive</I></B>.</DT>
+	<DT>
+	<IMG SRC="../images/stream_active_sink.gif" NAME="Rahmen2" ALT="Rahmen2" WIDTH=296 HEIGHT=165 BORDER=0/>
+	</dt><dt>
+	2) A <B><I>datasource</I></B> is <B><I>active</I></B>
+	when in the thread of execution the datasource calls a method of
+	datasink to write some data. In this case, the <B><I>datasink</I></B>
+	is <B><I>passive</I></B>.</DT><DT>
+	<IMG SRC="../images/stream_piping.gif" NAME="Rahmen3" ALT="Datasink passive diagram" WIDTH=296 HEIGHT=159 BORDER=0 />
+	</DT><DT STYLE="margin-bottom: 0.5cm">
+	Streams offer fixed interfaces to do the data transfer.
+	At the lowest level, streams transport bytes. Data does not need to be
+	transported in one piece but can be sliced into multiple pieces. To
+	reflect the two cases above, there exist <B>inputstreams</B> and
+	<B>outputstreams</B>. Inputstreams are used in the active
+	sink-passive source scenario and outputstreams are used in the
+	active source-passive sink scenario.</DT></DL>
+
+<!-- ************************ T H E   I N T E R F A C E S ******************************** -->
+<h2 id="the_interfaces"> The interfaces </h2>
+
+<DL>
+	<DT STYLE="margin-bottom: 0.5cm">The design of the streaming
+	interfaces had three major goals :</DT></DL>
+<UL>
+	<LI>
+	Easy to implement and short interface. Few interfaces to start with.
+	Extension interfaces to make the component more flexible and
+	reusable.
+	<LI>Allow easy <I>chaining</I> and
+	<I>piping</I> of streams (see below).
+	<LI>Symmetric interfaces. The input/output symmetry of the
+	problem should be reflected by the interfaces.
+</UL>
+<DL>
+	<DT>Below you can find the results of the design.
+	</DT><DT>
+	There is a kind of a four-level hierarchy indicated by the dotted lines.
+	</DT><DT STYLE="margin-bottom: 0.5cm">
+	<IMG SRC="../images/stream_interfaces.gif" NAME="Grafik1" WIDTH=632 HEIGHT=682 BORDER=0 alt="Stream interfaces"/>
+	</DT><DT STYLE="margin-bottom: 0.5cm">
+	<FONT SIZE=2><I>Fig 5. The new streaming interfaces in a 4 level
+	structure</I></FONT></DT></DL>
+
+<H4> The 1<SUP>st</SUP> level : XInputStream/XOutputStream </H4>
+
+<DL>
+	<DT>A basic streaming facility can be
+	implemented with XInputStream or XOutputStream alone.</DT><DT>
+	Example (see also the <a href="#introduction">introduction chapter</a>) :</DT>
+	<DT STYLE="margin-bottom: 0.5cm">
+	There is an object source that has some data, and an
+	object sink that wants to get some data. There are two possibilities
+	to fulfil the task :
+	</DT></DL>
+
+<UL>
+	<LI>
+	source implements an XInputStream and sink reads
+	actively from it. In this case, source is a <B><I>passive-data-source</I></B>
+	and sink is an <I><B>active-data-sink</B>.</I>
+	<LI>sink implements an XOutputStream and source
+	writes actively into it. In this case, source is an
+	<B><I>active-data-source</I></B> and sink is a <B><I>passive-data-sink.</I></B>
+</UL>
+<DL>
+	<DT STYLE="margin-bottom: 0.5cm">Sample implementation
+	( for simplicity no error handling here ).
+	</DT></DL>
+
+<PRE>//simple scenario : 200 bytes shall be transfered from source to target
+//active sink, passive source scenario.
+class source : public XInputStream, public ....
+{
+     ...
+     // set the actual position to zero
+     source() { index = 0; }
+
+     // XinputStream.readBytes()
+     INT32 readBytes( Sequence&lt;unsigned char&gt; &amp;seq , INT32 nBytes )
+     {
+          // beware eof !
+	  INT32 nCopy = min( nBytes, 200-index );
+
+          // allocate memory for the requested number of bytes
+          seq.realloc( nCopy );
+
+          // put the data into the sequence
+          memcpy( seq.getArray() , &amp;acData[index] , nCopy );
+
+          // increase actual position
+          index += nCopy;
+
+          return nCopy;
+     }
+
+     // XInputStream.skipBytes()
+     INT32 skipBytes( INT32 nBytes )
+     {
+          // beware eof !
+          INT32 nCopy = min( nBytes, 200-index );
+
+          // increase actual position
+          index += nCopy;
+
+          return nCopy;
+      }
+
+     // XInputStream.available()
+     INT32 available()
+     {
+        return 200-index;
+     }
+
+     // XInputStream.closeInput()
+     void closeInput()
+     {
+         // no special closing procedure in this simple example
+     }
+
+     ...
+private:
+     unsigned char acData[200];
+     INT32 index;
+};
+
+
+// the active datasink
+// No error or exception handling for simplicity
+class sink : public XXXXXXX, .....
+{
+     // method of interface XXXXXXX
+     void readFromStream( const Reference&lt; XInputStream &gt; &amp;r )
+     {
+         Sequence&lt;unsigned char&gt; seq(10);
+
+         BOOL bContinue = TRUE;
+
+         // number of bytes that have been read
+         INT32 nRead;
+
+         while( bContinue ) {
+             // read from the inputstream in 10 byte steps
+             nRead = r-&gt;readBytes( seq , 10 )
+
+             // ... do something with seq
+
+             // check, if eof has been reached
+	      bContinue = ( 10 == nRead );
+         }
+         // close the stream
+         r-&gt;closeInput();
+     }
+}
+
+///in main :
+{
+      Reference< XInterface > source;
+      Reference< XInterface > sink;
+
+      // instantiate source and sink through some service.
+      ....
+
+      // query the inputstream
+      Reference< XInputStream > input_stream( source , UNO_QUERY );
+
+      // query the sink
+      Reference< XXXXXXX > some_interface( sink , UNO_QUERY );
+
+      // do the reading
+      some_interface-&gt;readFromStream( input_stream );
+}
+</pre>
+
+<h4> The 2<SUP>nd</SUP> level : XActiveDataSink2/XActiveDataSource2 </h4>
+  <dl>
+	<dt style="margin-bottom: 0.5cm">To make the above sample code more
+	flexible, the sink class may
+	implement XActiveDataSink. Calling the setInputStream()-method
+	informs the sink from where to read the data. Thus the code becomes
+	more generic, (sink is only required to support the small
+	XActiveDataSink rather than Reference&lt; XXXXXXX &gt; ).</DT>
+	<DT style="margin-bottom: 0.5cm">
+	When to start the data transfer, depends on the implementer of
+	XActiveDataSink.
+	</DT>
+	<DT STYLE="margin-bottom: 0.5cm">
+	Here there are three possibilities.
+	</DT></DL>
+<OL>
+	<LI> In the call to XActiveDataSink.setInputStream() the whole data
+	transfer is done. This is the worst possibility, because a user may
+	not expect a set-method to behave this way.
+
+	<LI>The call to
+	XActiveDataSink.setInputStream() starts a thread that does the
+	data transfer. This is a better solution, because the call is not
+	blocking. Nevertheless the user must still be aware, that everything
+	is well prepared for transfer when the call is made.
+	
+	<LI>The call to XActiveDataSink2.setInputStream() just informs
+	the object where to read from. The start of data transfer is done
+	over another method. This may be the start()-method of
+	XActiveDataContro2 (see below).
+</OL>
+
+<DL>
+	<DT>The 3<SUP>rd</SUP> solution is by far the best one, because 1) +
+	2) are more difficult to reuse and may lead to deadlocks, etc.</DT>
+	<DT>
+	Note that everything said about XActiveDataSink also holds for
+	XActiveDataSource.</DT>
+</DL>
+
+<h3> 2.2.1 Chaining </h3>
+<DL>
+	<DT>An interesting application of the first 2 interface-levels is
+	the <B>chaining</B> concept.
+	</DT>
+	<DT>
+	Imagine you have written the XInputStream implementation OFile, that
+	offers raw data stored in a file. Then you have an arbitrary
+	application, that has implemented XActiveDataSource. After you have
+	connected both objects via setInputStream(), you have the connection
+	shown in Fig. 6a.</DT>
+	<DT>
+	<IMG SRC="../images/stream_chaining.gif" NAME="Rahmen6" ALT="Rahmen6" WIDTH=586 HEIGHT=349 BORDER=0/>
+	</DT><DT>
+	Now a file shall be read, that uses a different file format. One
+	could either modify OFile or application to do the conversion, but
+	there is a better solution. An independent service OConverter can be
+	used, it implements XActiveDataSink and XInputStream. Now the input
+	stream of OFile can be plugged into OConverter and the input stream
+	of OConverter can be plugged into application (Fig 6.b).</DT><DT>
+	Note that it is not necessary to change either application or OFile,
+	only the plugging before the start of data transfer must be adapted.
+	If desired, this may be decided at runtime.</DT>
+	<DT>
+	Note also, that you can easily insert more converters into the
+	chain.
+	</DT>
+</DL>
+
+<PRE>The following code samples show how plugging is done.
+/// Plugging for Fig 6b (without error handling)
+{
+     Reference&lt;XInterface &gt; application;
+     Reference&lt;XInterface &gt; OConverter;
+     Reference&lt;XInterface &gt; OFile;
+
+     // instantiate the three objects via services, put them into the above references
+     .....
+
+     // query the interfaces
+     Reference&lt; XInputStream &gt; aFileInputStream( OFile , UNO_QUERY );
+     Reference&lt; XInputStream &gt; aConverterInputStream( OConverter , UNO_QUERY );
+     Reference&lt; XActiveDataSink &gt; aConverterSink( OConverter , UNO_QUERY );
+     Reference&lt; XActiveDataSink &gt; aApplicationSink( application , UNO_QUERY );
+
+     // plug the connection
+     aConverterSink.setInputStream( aFileInputStream );
+     aApplicationSink.setInputStream( aConverterInputStream );
+
+     // start data transfer
+     ...
+}
+</PRE>
+
+  <dl>
+	<DT>
+	The following figure shows the resulting calling sequence for a
+	readBytes()-call for both cases.</DT><DT>
+	<IMG SRC="../images/stream_read.gif" NAME="Rahmen7" ALT="Rahmen7" WIDTH=356 HEIGHT=260 BORDER=0/>
+	<DT>
+	<IMG SRC="../images/stream_read_and_convert.gif" NAME="Rahmen8" ALT="Rahmen8" WIDTH=570 HEIGHT=363 BORDER=0/>
+	</DT>
+	<DT>
+	Note that the <B>order of plugging</B> may be significant if
+	data transfer is started with the setInputStream method. Again the
+	last line of the above sample code :</DT><DT STYLE="margin-bottom: 0.5cm">
+	a)
+	</DT>
+</DL>
+
+<PRE>{
+   // plug the connection
+   aConverterSink.setInputStream( aFileInputStream );        // first connect passive parts.
+   aApplicationSink.setInputStream( aConverterInputStream ); // active player is connected last,
+                                                             // no problems can arise
+}
+
+b)
+{
+   // plug the connection
+   aApplicationSink.setInputStream( aConverterInputStream ); // application starts to read but OConverter
+   // is not connected to anything.
+   aConverterSink.setInputStream( aFileInputStream );
+}
+</PRE>
+
+<p>The problem can be avoided :</p>
+
+<OL>
+	<li> Use code sample a) instead of b) when plugging. ( Responsibility
+	is left to the user ). When b) is used, OConverter will throw an
+	exception.
+
+	<li>OConverter can be designed, so that it can cope with the problem. If
+	it is not connected to anything, but its read()-method is called, it
+	could wait in a condition up to the moment when connection is
+	established. Note that this is not an ideal solution, if the
+	connection never gets established there remains a dead thread
+	without any sign of an error. It also must be implemented again and
+	again for each converter.
+
+	<LI>Do not start the data transfer with these set-methods. Better
+	use XActiveDataControl (see below)
+</OL>
+
+<DL>
+	<DT>
+	Note : It can be quite difficult to implement a OConverter, that
+	modifies the number of bytes to read. The skipBytes(), readBytes()
+	and available()-methods must always return the requested number of
+	bytes, in such cases, converters must do at least some buffering on
+	their own. For such applications it is in general easier to
+	implement an output stream (and use pipes and threads to get the
+	desired interface, see below). However this may be too expensive in
+	some cases.</DT>
+</DL>
+
+<h3> 2.2.2 Piping </h3>
+
+<DL>
+	<DT>Motivation :</DT><DT>
+	For a lot of applications it is necessary to have more than one
+	active player in the game. Imagine you have a datasource that can
+	only write actively and a datasink that can only read actively and
+	you want to connect them. This can be done by a pipe. A pipe offers
+	an OutputStream to write to and an InputStream to read from. Thus it
+	must buffer the data that come in via XOutputStream.</DT>
+	<DT>
+	Fig. 9 shows a concrete example for a pipe. A file x is copied into
+	file y. OFileReader reads file x in certain slices. Each slice is
+	written via the output stream to OPipe. OFileWriter gets actively data
+	from OPipe and writes it directly into file y. The connection is
+	plugged with standard components (which still need to be
+	implemented), they can be used in other scenarios independent of
+	each other.</DT>
+	<DT>
+	<IMG SRC="../images/stream_piping.gif" NAME="Rahmen9" ALT="Rahmen9" BORDER=0/>
+	</DT><DT STYLE="margin-bottom: 0.5cm">
+	The following source code shows how the above connection is
+	established (for simplicity without error handling).</DT></DL>
+
+<PRE>
+{
+     Reference&lt; XInterface &gt; OFileWriter, OPipe, OFileReader;
+
+     // instantiate them via a standard service
+     ....
+
+     // get the interfaces
+     Reference&lt; XActiveDataSink &gt; sink( OFileWriter, UNO_QUERY );
+     Reference&lt; XOutputStream &gt; pipeOut( OPipe , UNO_QUERY );
+     Reference&lt; XInputStream &gt; pipeIn( OPipe , UNO_QUERY );
+     Reference&lt; XActiveDataSource &gt; source( OFileReader , UNO_QUERY );
+
+     // do the plugging
+     sink.setInputStream( pipeIn );
+     source.setOutputStream( pipeOut );
+     // now work with the connection ( sink and source )
+}
+</PRE>
+
+ <dl>
+   <DT>
+	Note : You can insert further filters and converters via chaining.
+	For example you can insert an instances of OConverter (above example)
+	between OFileWriter and OPipe.</DT>
+	<DT>
+	Note : A pipe can also be seen as a mechanism to transform an output
+	stream into an input stream at the costs of the buffer resources.</DT>
+	<DT>
+	Note : By exchanging OFileWriter with an object that implements
+	XActiveDataSink and XActiveDataSource, one could add a further
+	pipe. This shows the flexibility of the concept.</DT>
+	</DL>
+
+<H4> The 3<SUP>rd</SUP> level : XActiveDataControl </H4>
+
+<DL>
+	<DT>The question 'when should data transfer start ?' is not solved
+	sufficiently. One can say that as soon as the last connection has
+	been plugged, the data starts to flow. That is not acceptable for
+	some applications. An generic interface is needed, which can one use
+	to initiate the data transfer. This is the role of
+	XActiveDataControl.</DT>
+	<DT>
+	XActiveDataControl should be implemented with XActiveDataSink or
+	XActiveDataSource, thus each active player in the game should
+	implement it.</DT>
+	<DT>
+	XActiveDataControl offers a non-blocking start()-method to initiate
+	data transfer. The terminate()-method should abort the data transfer
+	before it is normally finished. Usually this should be done by
+	calling the close()-method of the connected streams. See error
+	handling for further information.</DT>
+	<DT STYLE="margin-bottom: 0.5cm">
+	<IMG SRC="../images/stream_datacontrol.gif" NAME="Rahmen10" ALT="Rahmen10" WIDTH=559 HEIGHT=229 BORDER=0/>
+	</DT></DL>
+
+<PRE>
+To startup the above sample pipe, the following code is necessary :
+{
+     Reference&lt; XInterface &gt; OFileWriter, OPipe, OFileReader;
+
+     // instantiate them via a standard service
+     ....
+
+     // get the interfaces for plugging
+     Reference&lt; XActiveDataSink &gt; sink( OFileWriter, UNO_QUERY );
+     Reference&lt; XOutputStream &gt; pipeOut( OPipe , UNO_QUERY );
+     Reference&lt; XInputStream &gt; pipeIn( OPipe , UNO_QUERY );
+     Reference&lt; XActiveDataSource &gt; source( OFileReader , UNO_QUERY );
+
+     // plug ( data transfer is not started )
+     sink.setInputStream( pipeIn );
+     source.setOutputStream( pipeOut );
+
+     // get the interfaces for starting
+     Reference&lt; XActiveDataControl &gt; controlSink( OFileWriter );
+     Reference&lt; XActiveDataControl &gt; controlSource( OFileReader );
+
+     // start
+     controlSink.start();   // order of starting is not important, the whole connection already exists.
+     controlSource.start(); // it may be less expensive to start sink first, because OPipe
+                            // may need less resources for buffering.
+}
+</PRE>
+
+<p>XActiveDataControl also offers a listener administration.</p>
+
+<H4> The 4<SUP>th</SUP> level : XConnectable</H4>
+
+<DL>
+	<DT>The held references in Fig. 10 are unidirectional. There is no
+	generic way to get from OFileWriter to OFileReader. This maybe
+	interesting for further streaming administration services.</DT>
+	<DT>
+	Here now appears XConnectable on stage. Every class in the
+	connection should implement XConnectable. Below (Fig.11 and Fig.
+	12) you find the extended version of the above examples.</DT><DT>
+	<IMG SRC="../images/stream_connected_chain.gif" NAME="Grafik2" WIDTH=669 HEIGHT=240 BORDER=0 alt="Stream connected chain"/><br clear=left/>
+	<FONT SIZE=2><I>Fig
+	11. Extended example (see fig. 6b). Each element in the connection
+	implements XConnectable and connects to their neighbours. Thus it is
+	possible to reach Application from OFile. The direction of the
+	connection (successor/predecessor) is determined by the direction
+	of dataflow.</I></FONT></DT><DT>
+	<IMG SRC="../images/stream_connected_pipe.gif" NAME="Grafik6" WIDTH=559 HEIGHT=259 BORDER=0 alt="Stream connected pipe"/><br  clear=left/>
+
+	<I>Fig
+	12. Extended example (see fig 10). Now every element of the
+	connection is reachable with one arbitrary element.</I></DT>
+	<DT STYLE="margin-bottom: 0.5cm">
+	The extra plugging work should not be left to the user. In order to
+	get this working with the least effort for the user, the
+	implementation of the XActiveDataSink.setInputStream() or
+	XActiveDataSource2.setOutputStream() must be modified the following
+	way:</DT></DL>
+<PRE>
+OFileWriter::setInputStream( const Reference&lt; XInputStream &gt; &amp;r )
+{
+     /// store the inputstream reference for later use
+     m_in = r;
+
+     /// does the instance provide a XDataSourceRef ?
+     Reference&lt; XConnectable &gt; predecessor( r , UNO_QUERY );
+     setPredecessor( predecessor );
+}
+
+application::setPredecessor( const Reference&lt; XConnectable &gt; &amp;r )
+{
+     /// if the references match, nothing needs to be done
+     if( m_pred != r ) {
+         /// store the reference for later use
+         m_pred = r;
+
+         if( m_pred.is() ) {
+              /// set this instance as the sink !
+              m_pred.setSuccessor( this );
+         }
+     }
+}
+
+</PRE>
+ <dl>
+   <dt>
+	A similar implementation of for setSuccessor allows to get the
+	desired references with no extra work for the user.</DT>
+	<DT>
+	There now exists a <B>ring reference</B>, which raises a
+	deallocation-problem. This can be solved sufficiently, when in
+	close()-operations all references are explicitly deleted.</DT><DT STYLE="margin-bottom: 0.5cm">
+	OConverter::closeInput()</DT></DL>
+<PRE>{
+     /// send the close to the chained partner
+     getInputStream()-&gt;closeInput();
+
+     //.... do some tiding up, that is necessary when closing.
+
+     /// release all references
+     setPredecessor( Reference&lt; XConnectable &gt;() );
+     setSource( Reference&lt; XConnectable &gt;() );
+     setInputStream( Reference&lt; XInputStream &gt;() );
+}
+</PRE>
+<p>Note that any object, which does not support this XConnectable mechanism will interrupt the connection.
+
+<dl>
+<DT style="margin-bottom: 0.5cm">
+	The sense of XConnectable is maybe not very clear. Note that
+	implementing this underlying connection of elements will allow to
+	create standard services, that can help to establish and
+	administrate connections of streams. This may be an important reason
+	for using this new streaming interfaces, that's why you are strongly
+	encouraged to implement them.
+	</DT><DT STYLE="margin-bottom: 0.5cm">
+	An use case may be a video stream, where the sink wants to change
+	some settings at source, but the sink doesn't know the source. It
+	can then use XConnectable to wander to the source, where it can
+	query on a known interface.</DT></DL>
+
+<H3> 2.5 Errorhandling </H3>
+
+<DL>
+	<DT>This chapter deals with abnormal conditions that may occur when
+	using streams.</DT><DT>
+	<IMG SRC="../images/stream_connected_pipe.gif" NAME="Grafik5" WIDTH=559 HEIGHT=259 BORDER=0 alt="Stream connected pipe"/>
+	</DT><DT>
+	Let's take the <B>pipe</B> example as a basis for discussion.</DT>
+	<DT>
+	In the normal case both FileReader and FileWriter start to do their
+	job. When FileReader has read all data from the file x and has
+	written all data into the outputstream, it must call closeOutput on
+	XOutputStream. This will disconnect OPipe and OFileReader,
+	OFileReader may be deleted. When OFileWriter tries to read beyond
+	eof, it realizes that it gets less bytes than questioned. This is
+	interpreted by OFileWriter as eof sign. It then calls closeInput on
+	the XInputStream and frees its own resources. The reference between
+	OPipe and OFileWriter is removed, OFileWriter and OPipe may be
+	deleted.
+	</DT>
+	<DT STYLE="margin-bottom: 0.5cm">
+	Possible error scenarios are :</DT></DL>
+<OL>
+	<LI>
+	Error during reading file x (OFileReader). In that case OFileReader
+	closes its internal resources, broadcasts an error to all listeners
+	and calls closeOutput() on outputstream. Note that OPipe and
+	OFileWriter cannot distinguish between a normal eof-close and a
+	error close (unless they are listeners).
+
+	<LI>Error during writing file y
+	(OFileWriter). In that case, OFileWriter closes its internal
+	resources, broadcasts an error to all listeners and calls
+	closeInput() (which will disconnect OFileWriter from OPipe ) on
+	inputstream. OFileReader is still writing on OPipe's outputstream.
+	At any time after the closeInput() call, OPipe may throw an
+	IOException, if OFileReader calls a write-method. OFileReader
+	catches the exception, calls closeOutput() on the outputstream,
+	which will disconnect OPipe from OFileReader. It may also broadcast
+	an error to all listeners.
+
+	<LI>Error in OPipe (e.g. buffer full).
+	At any time after the exceptional state has occurred, OPipe will
+	throw exceptions for every read call and every write call.
+	OFileReader and OFileWriter must then call
+	closeInput()/closeOutput() and broadcast an error.
+
+	<LI>terminate()-method on OFileReader or OFileWriter is called.
+	This can be handled very similar to the above error conditions,
+	except that the terminated()-handler must be called.
+</OL>
+<DL>
+	<DT STYLE="margin-bottom: 0.5cm">
+	Note that all above errors in general occur in a multi-threaded
+	environment. Especially situations as that the terminate()-method of
+	OFileWriter gets called when another thread is in the read-Method of
+	OPipe must be handled correctly. In this case, terminate must call
+	closeInput(), OPipe must return out of the reading thread with
+	eof-signature (less bytes read than questioned) and OFileWriter must
+	call only the terminated() but not the error() handler!.</DT></DL>
+
+<!-- ************************ I N T R O D U C T I O N *************************************** -->
+<h2 id="standard_services"> Standard services </h2>
+
+<p>The following standard services have been implemented . Implementations
+can be found in udk/io/source/stm.
+The dll is <B>stm.dll</B>.
+All implementations are thread safe. However it is probably not very
+meaningful, if two threads read the same input stream at the same
+time which thread gets which data is then arbitrary.
+
+<p>Note: All streams must be explicitly closed in order to free their resources
+and release their ring references.</p>
+
+<P><B>com.sun.star.uno.io.Pipe :</B>
+implements <I>XOutputStream</I>, <I>XInputStream</I> and
+<I>XConnectable</I></p>
+<p>Basic implementation (see fig 12) to connect
+input stream and output stream. In general one thread is writing data
+into the pipe and another is reading from the pipe. The pipe does the
+necessary buffering in memory.</P>
+
+<P><B>com.sun.star.uno.io.DataInputStream
+: </B>implements <I>XDataInputStream</I>, <I>XActiveDataSink</I> and
+<I>XConnectable</I></p>
+<p>Provides the XDataInputStream functionality.
+Must be chained to another XInputStream (e.g. a pipe) to be
+meaningful.</P>
+
+<P><B>com.sun.star.uno.io.DataOutputStream</B>
+: implements <I>XDataOutputStream</I>, <I>XActiveDataSource</I> and
+<I>XConnectable</I></p>
+<p>Provides the XDataOutputStream functionality.
+Must be chained to another XOutputStream (e.g. a pipe) to be
+meaningful.</P>
+
+<P><B>com.sun.star.uno.io.MarkableInputStream
+: </B>implements <I>XMarkableStream</I>, <I>XInputStream</I>,
+<I>XActiveDataSink</I> and <I>XConnectable</I></p>
+<p>Provides the
+XMarkableStream functionality. When a mark is created, the
+implementations buffers all further read data. Must be chained to
+another inputstream to be meaningful.</P>
+
+<P><B>com.sun.star.uno.io.MarkableOutputStream
+: </B>implements <I>XMarkableStream</I>, <I>XOutputStream</I>,
+<I>XActiveDataSource</I> and <I>XConnectable</I></p>
+<p>Provides the
+XMarkableStream functionality. When a mark is created, the
+implementations buffers all further written data. The data is written
+further through the chain, when the mark is deleted. Even a flush
+will not have any effect. Must be chained to another outputstream to
+be meaningful.</P>
+
+<P><B>com.sun.star.uno.io.ObjectInputStream
+: </B>implements <I>XObjectInputStream</I>, <I>XActiveDataSink</I>
+and <I>XConnectable</I></p>
+<p>Provides XObjectInputStream functionality.
+All services of instances, that shall be read, must be registered
+with the global service manager. All services must implement
+XPersistObject. Must be chained to another XInputStream. Somewhere in
+the chain <B>must</B> exist an XMarkableStream.
+Be careful that all elements between this and XMarkableStream <B>must
+not</B> buffer data ( otherwise the markable stream becomes
+meaningless ) and one receives coincident results.</P>
+
+<P><B>com.sun.star.uno.io.ObjectOutputStream</B>
+: implements <I>XObjectOutputStream, XActiveDataSource</I> and
+<I>XConnectable</i></p>
+<p>Provides XObjectOutputStream functionality.
+All services, that shall be serialized, must implement
+<I>XPersistObject.</I> Must be chained to another XOutputStream.
+Somewhere in the chain <B>must exist </B>a XMarkableStream. Be
+careful that all elements between this and XMarkableStream <B>must
+not </B>buffer data ( otherwise the markable stream becomes
+meaningless) and one receives coincident results.</P>
+
+<table summary=footer width=100% bgcolor=#666699>
+<tr>
+<td>
+ <p><font color="#ffffff"> Author: 
+ <a href="mailto:joerg.budischewski@germany.sun.com"> <font color=#ffffff>Joerg Budischewski</font></a>
+ ($Date: 2004/11/27 07:50:15 $)<br/>
+ <i>Copyright 2001 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, CA
+ 94303 USA.</i></font>
+ </p>
+</td>
+</tr>
+</table>
+</BODY>
+</HTML>

Propchange: incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/streams.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/string_invest.html
URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/string_invest.html?rev=1206895&view=auto
==============================================================================
--- incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/string_invest.html (added)
+++ incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/string_invest.html Sun Nov 27 22:49:46 2011
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+        <meta http-equiv="refresh" content="3; URL=http://wiki.services.openoffice.org/wiki/Uno/Binary/Analysis/String_Performance" />
+<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
+</head>
+<body>
+<p class="Header">Redirecting....</p>
+
+</body>
+</html>

Propchange: incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/string_invest.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/uno_contexts.html
URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/uno_contexts.html?rev=1206895&view=auto
==============================================================================
--- incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/uno_contexts.html (added)
+++ incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/uno_contexts.html Sun Nov 27 22:49:46 2011
@@ -0,0 +1,830 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1"/>
+<TITLE>
+UNO Contexts
+</TITLE>
+<style type="text/css">
+	<!--
+h1 { text-align:center; margin-top: 0.2cm; text-decoration: none; color: #ffffff; font-size: 6; margin-top: 0.2cm}
+h2 { margin-top: 0.2cm; margin-bottom=0.1cm; color: #ffffff;
+     background-color: #666699 }
+li {margin-bottom: 0.2cm;}
+dl {margin-bottom: 0.2cm;}
+dd {margin-bottom: 0.2cm;}
+dt {margin-bottom: 0.2cm;}
+-->
+</style>
+</HEAD>
+<BODY>
+<TABLE WIDTH=100% BORDER=0 CELLPADDING=4 CELLSPACING=0 BGCOLOR="#666699">
+<TR><TD>
+      <h1> UNO Contexts </h1>
+  </td><td>
+	  <A HREF="http://www.openoffice.org/">
+        <IMG SRC="../../../images/open_office_org_logo.gif" NAME="Grafik1" ALT="OpenOffice.org" ALIGN=right WIDTH=109 HEIGHT=54 BORDER=0 alt="OpenOffice.org"/>
+        </A>
+    </TD></TR>
+
+</TABLE>
+
+<h2> Contents </h2>
+
+      <p><a href="#abstract">Abstract</a></p>
+      <p><a href="#intro">Introduction to Contexts</a></p>
+      <p><a href="#component_context">Component Context</a>
+      <ul>
+      <li><a href="#context_interface">Context Interface</a></li>
+      <li><a href="#factory_context">Factory Context</a></li>
+      <li><a href="#instance_context">Instance Context</a></li>
+      </ul>
+      <p><a href="#current_context">Current Context</a></p>
+      <p><a href="#component_descr">Extensions to the XML Component Description</a></p>
+      <p><a href="#oneinstance">Migration path for existing OneInstance services</a></p>
+      <p><a href="#todos">Things left to do...</a></p>
+
+<h2 id="abstract">Abstract </h2>
+
+<p>This draft is about UNO contexts; what they are, how and under what condition
+        they make sense, and when you should use them. UNO contexts are generic
+        containers for storing arbitrary values that are either used by components
+        to get their deployment settings or control the runtime behavior of a
+        component.</p>
+        <p>Contexts are classified into static (component) contexts and dynamic (current)
+        contexts. A component context provides a component's deployment values;
+        a current context provides task-local values, such as values that are transferred
+        implicitly via a chain of calls excluding other tasks having access to
+        these values.</p>
+        <p>The following section, <a href="#intro"><i>Introduction</i></a>,
+        introduces the topic with an example.
+				The next two sections (<a href="#component_context"><i>Component
+        Context</i></a> and <a href="#current_context"><i>Current Context</i></a>)
+        present a definition and API proposal for the component and current context
+        as well as a migration path for the current API.</p>
+        <p>Finally, the last section proposes <a href="#component_descr"><i>Extensions to the XML Component Description</i></a>, 
+        
+	<a href="http://udk.openoffice.org/common/man/module_description.html">component description</a> by describing deployment properties of a component
+        implementation and invariants.
+      </p>
+
+<h2 id="intro"> Introduction </h2>
+
+	  <p>A component implements a service (defined in UNO-IDL), that is, at
+	    least the defined set of supported
+        interfaces of the service. The service builds up the contract
+        between component implementor and component user which is the way a component
+        can be accessed and used. In general, interfaces abstract from system
+        and implementation details to allow that a component implementation may
+        be exchanged for another. Therefore, component users should generally
+        not rely on a actually running component implementation. This is a desired
+        feature of components: handle them as isolated as possible. Changing
+        an interface or in general changing the way a component's functionality
+        is accessed is difficult, because client code has to be revisited
+        even for minor changes.
+		This is not always possible, if, for example, software has been
+		developed by 3rd party engineers.  </p>
+      <p><img src="../images/context_example1.gif" align=right hspace=60 alt="context example"/> For
+        further explanations, consider the following example:
+	A DataService is providing
+        data in a generic way, abstracting from the specific sources from which it gets
+        the data.  This approach is often chosen in software systems, because
+	it is a flexible way of extending to unknown data sources, thus avoiding
+	the need to touch the DataService.</p>
+	<p>Specific DataProvider components are plugged under
+	the generic DataService. The user runs the DataService giving a uniform
+	address for the data he wants to access, not knowing which specific
+	DataProvider is performing the request. The latter concerns
+	deployment aspects of actually existing data sources on the machine.</p>
+    <p>Running the example component on a big machine, you may want to switch
+        on caching of data to speed up access. Also, in keeping the set of interfaces
+        small, the service should not directly export an interface like <code>XCache</code>
+        or have interfaces polluted by caching flags in its access methods. The
+        set of interfaces and their methods should be kept minimal for extensive
+        use.</p>
+     <p>You also don't want to be implementing another set of interfaces
+        just to support caching functionality. It is even worse if the
+        DataProviders access further sub-services that should take caching into
+        account. In the latter case, every calling instance has to manage the
+        caching settings being propagated to the called instance. Eventually,
+        not all sub-services support caching functionality, but need
+        to forward the setting without knowing anything about it.</p>
+     <p>Last, you want a sensible (thus often different) caching policy being
+	deployed, if your application is being installed on a small or a big machine.
+	</p>
+      <p><b>Consequences</b></p>
+	  <p>You want to parameterize a components' implementation, even if it is
+	     accessed indirectly in a somehow weaker way than thru IDL interfaces.</p>
+	  <p>To state clearly: Of course, it is always the best solution to
+	    specify a component
+        comprehensively by IDL interfaces, but it is also common sense to keep
+        a service description as minimal (but sufficient) and generic as possible,
+        and avoid specifics of the underlying system.</p>
+       <p>This creates a conflict: In general, it is forbidden to use anything
+        out of a service's implementation that is not part of the service description.
+        So, by definition, you can only depend (and rely) on the service description.
+        On the other hand, as stated above, you may want it for convenience and
+        API design reasons. So there is no silver bullet, for the minority
+        of cases where one needs a possibility to customize a component's implementation
+        in a documented way.</p>
+      <p><b>Solution Proposal</b></p>
+      <p>A convenient (extendable) solution would be, if each component were
+		granted a set of named properties when it is raised. This is called a
+		UNO context. It provides deployment data to the component.</p>
+	  <p>Upon raising further component
+		instances, the set of properties (context) is forwarded.  The actually
+		affected component of a property takes it into account and behaves as
+		documented (see <a href="#component_descr">
+	extensions to the XML component description</a>). All other instances, in the
+        chain of raised components, ignore settings that are unknown to them. So
+        the modification of a property requires global knowledge about what
+        components get affected. You have to know if a specific property will
+        be taken into account, but <b>not</b> necessarily by which component
+        instance, in general, you don't know what further components are instantiated
+		when raising a specific component (this is an implementation detail).
+		The latter point requires a clear documentation scheme of a component's
+		deployment properties.
+	  </p>
+	  <p>The previous example states the deployment of a component, that is
+		when the component is installed for example by an application
+		installation. Enabling or disabling caching, the cache size, et cetera
+		-- these properties are basically
+        of a static nature, because the underlying system won't change during execution
+        of the application. For flexibility, there may be the need to switch it
+        on or off depending on the current system load. You may do this on a per-instance
+        basis (customizing a component instance) or  per-call basis (customizing for the
+        current execution only). The latter aspect is clearly of a dynamic nature.
+      An example usage case may be a low-level socket API, extended by error handling
+      capabilities without changing the socket API.
+      </p>
+      <p>
+        To summarize the above:</p>
+      <ul>
+        <li><p>deployment properties for component implementations,</p></li>
+        <li><p>public definition and documentation of properties (this may include
+          invariants to test consistent deployment),</p></li>
+        <li><p>implicit propagation of properties when raising further components,</li>
+        <li><p>static customization: per component class (deployment) and per instance,</p></li>
+        <li><p>dynamic customization: per call.</p></li>
+      </ul>
+      <p>All of the mentioned customization of UNO components
+        is referred to as "UNO contexts". A UNO context delivers additional
+        runtime information for component execution. UNO contexts provide a set
+        of named values like a property bag. You can retrieve values by
+		their names; this is flexible for modifications without changing the
+		context interface.</p>
+	  <p>There is a distinction between static and dynamic contexts: A static
+	    context
+        (also referred as the "component context") may be used simultaneously
+	(e.g. by multiple threads), is immutable,
+        and is commonly given when a component is instantiated. The component
+        context is divided into a factory context that is accessible by all instances
+        of a component and provides persistent values to the component.
+        In addition, there is the specific component context given at instantiation
+        time, which was eventually customized by the caller that raised the component
+        instance.
+        In contrast, a dynamic context (also referred as the "current context")
+        is implicitly provided by a calling task (e.g. a calling thread)
+        to the component.</p>
+	   <p>The previous example sketched again, modifying the DataProvider's
+	    caching behavior on a per-instance basis:</p>
+        <p>
+        <img src="../images/context_example2.gif" hspace=60 alt="another context example"/>
+        </p>
+	   <p>The caller prepares a context, putting the caching entry
+	    "DataProvider.CacheOn = true" before raising the DataService.</p>
+       <p>A subsequently called DataProvider1 recognizes a "DataProvider.CacheOn"
+        flag. DataProvider2 ignores the caching properties, because it does not
+        support caching at all.</p>
+       <p>The caching property is defined as "optional", meaning it need not be
+        set and the affected component may choose a default behavior if it is
+        not set. Another attribute for a customization property is "mandatory", 
+        stating that a property must be configured for running a component.</p>
+      <p>An automatic consistency test for a deployment involves, at least, the testing
+      of all invariants specified for properties. In general, invariants should
+      be implemented by the component that uses the involved properties.
+      Simple invariants may also be specified in the component description of
+      the implementation, e.g. <code>&lt;invariant type="min" value="128"/&gt;</code>.
+      For further details, have a look at the <a href="#component_descr">extensions
+      to the XML component description</a>.
+        </p>
+	<p>
+        In general, the following figure sketches context propagation along to several instances
+	(single factory context for all components):
+    <img src="../images/context_propagation.gif" hspace=20 alt="Context propogation" />
+
+<h2 id="component_context"> Component Context </h2>
+
+      <p><a name="context_interface"><b>Component Context Interface</b></a></p>
+	  <p> The
+	  <a href="http://api.openoffice.org/common/ref/com/sun/star/uno/XComponentContext.html">
+	  component context interface</a> is basically an interface for getting
+	  arbitrary values by their name.  A value once retrieved via the context
+	  interface will remain unmodified, which means, you retrieve the same
+	  value by calling it a second time (immutable).  Method
+	  <code>getServiceManager()</code> has been added, because the service
+	  manager instance is often needed by component implementations: </p>
+      <table width="100%" bgcolor="#ffffaa">
+        <tr>
+          <td>
+            <pre>
+module com { module sun { module star { module uno {
+
+interface XComponentContext : com::sun::star::uno::XInterface
+{
+    any getValueByName( [in] string Name );
+    com::sun::star::lang::XMultiComponentFactory getServiceManager();
+};
+
+}; }; }; };
+</pre>
+          </td>
+        </tr>
+      </table>
+      <p> The following enumeration shows common values of a static component
+        context, though not all properties need to be provided. If a component
+        could not run because of a missing property, it has to throw an exception,
+        for instance, <code>CannotActivateComponentException</code>. </p>
+      <ul>
+        <li><p><b>ServiceManager (<code>context property name="/singletons/com.sun.star.lang.theServiceManager"</code>)
+          : <code>type com.sun.star.lang.XMultiComponentFactory</code></b><br/>
+          A service manager to create and use further component instances. Every
+          <code>createInstance[WithContext]()</code> call will provide a distinct instance, no one-instance services
+          should be provided any longer. This is currently not possibly, because
+          of existing component implementations.</p>
+        </li>
+
+        <li><p><b>TypeDescriptionManager (<code>context property name="/singletons/com.sun.star.reflection.theTypeDescriptionManager"</code>)
+          : <code>type com.sun.star.container.XHierarchicalNameAccess</code></b><br/>
+          This singleton accesses the type library providing type information for UNO-IDL types
+	  </p>
+        </li>
+
+        <li><p><b>AccessController (<code>context property name="/singletons/com.sun.star.security.theAccessController"</code>)
+          : <code>type com.sun.star.security.XAccessController</code></b><br/>
+          An access controller instance to perform permission checks.
+	  This instance will use the policy singleton object to obtain user permission sets.
+	  </p>
+        </li>
+
+        <li><p><b>User Access Policy (<code>context property name="/singletons/com.sun.star.security.thePolicy"</code>)
+          : <code>type com.sun.star.security.XPolicy</code></b><br/>
+          A user policy object reading from some persistent storage providing user permission sets, such as, permissions granted to a user.
+	  </p>
+        </li>
+
+		<li><p><a name="singleton">Global</a> singleton objects are accessible
+		by their name which is prepended by <code>/singletons/</code>.  This
+		should further on be used for IDL declared singleton services, for
+		example,</p>
+      <table width="100%" bgcolor="#ffffaa">
+        <tr>
+          <td>
+            <pre>
+module com { module sun { module star { module reflection {
+
+singleton theTypeDescriptionManager
+{
+    service TypeDescriptionManager;
+};
+
+}; }; }; };
+</pre>
+          </td>
+        </tr>
+      </table>
+	  <p>declares a context entry
+	  <code>/singletons/com.sun.star.reflection.theTypeDescriptionManager</code>
+	  of an <code>TypeDescriptionManager</code> service object at runtime.  It
+	  is part of the deployment that this singleton is available and installed
+	  into the initial factory context at runtime.</p>
+	  <p>This service object will be raised "late" on first use and disposed
+	  when the component context is closed down (i.e. is disposed).  By
+	  default, each new component context wrapping an existing one (i.e.
+	  delegating unknown property requests to it) should add itself as event
+	  listener to dispose itself when the previous one is disposed (=&gt;
+	  chaining).</p>
+        </li>
+      <li>Additional properties of any type may
+        be provided by the context.
+	Those properties should be prefixed by <code>/implementations/<em>implementation-name</em></code> or <code>/services/<em>service-name</em></code>.
+	In the latter case, they need to be documented in the service description.
+      </li>
+      </ul>
+      <p><a name="factory_context"><b>Factory Context</b></a></p>
+	  <p>The factory context of a component is initialized when the system is
+	  started.
+        Commonly one factory context for all components is read out of a central
+        configuration database at startup of the service manager. All persistent properties
+        have to be provided to all factories, because it is in general <b>not</b>
+        known which component will use a property.</p>
+	   <p>Details about getting up the factory (deployment) context are not
+	   discussed
+        here, because this involves specific knowledge of the underlying storage
+        and the way the system is initialized.
+	Common storage formats
+        for OpenOffice.org are the applicat.rdb or the OpenOffice.org
+	<a href="http://util.openoffice.org/common/configuration/concepts.html">Configuration service</a>.
+	</p>
+	<p>A common cppuhelper API to bootstrap using a registry database (e.g. the applicat.rdb)
+	is presented <a href="http://wiki.services.openoffice.org/wiki/Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#Bootstrapping_the_initial_component_context_.28factory_context.29">here</a>.
+	Java support is also implemented.
+	</p>
+    <p><a name="instance_context"><b>Instance Context</b></a> </p>
+    <p>The service manager implementation is extended by supporting the
+	<code>XMultiComponentFactory</code> interface. The factory helpers are
+	extended by supporting
+	<a href="http://api.openoffice.org/common/ref/com/sun/star/lang/XSingleComponentFactory.html"><code>XSingleComponentFactory</code></a>
+	interface, too.
+	It has to be assured that the factory implementations acknowledge a given
+	context and
+	service manager instance at runtime (thus not referencing statically, but
+	on every <code>createInstanceWithContext()</code> call).</p>
+    <p>The user is creating a component instance by calling on the
+	<a href="http://api.openoffice.org/common/ref/com/sun/star/lang/XMultiServiceFactory.html"><code>XMultiServiceFactory</code></a>
+        (old) or
+	<a href="http://api.openoffice.org/common/ref/com/sun/star/lang/XMultiComponentFactory.html"><code>XMultiComponentFactory</code></a>
+	interface:</p>
+
+      <table width="100%" bgcolor="#ffffaa">
+        <tr>
+          <td>
+            <pre>
+module com { module sun { module star { module lang {
+
+interface XMultiComponentFactory : com::sun::star::uno::XInterface
+{
+    com::sun::star::uno::XInterface createInstanceWithContext(
+        [in] string ServiceSpecifier,
+        [in] com::sun::star::uno::XComponentContext Context )
+        raises (com::sun::star::uno::Exception);
+    com::sun::star::uno::XInterface createInstanceWithArgumentsAndContext(
+        [in] string ServiceSpecifier,
+        [in] sequence< any > Arguments,
+        [in] com::sun::star::uno::XComponentContext Context )
+        raises (com::sun::star::uno::Exception);
+    sequence< string > getAvailableServiceNames();
+};
+
+interface XSingleComponentFactory : com::sun::star::uno::XInterface
+{
+    com::sun::star::uno::XInterface createInstanceWithContext(
+        [in] com::sun::star::uno::XComponentContext Context )
+        raises (com::sun::star::uno::Exception);
+    com::sun::star::uno::XInterface createInstanceWithArgumentsAndContext(
+        [in] sequence< any > Arguments,
+        [in] com::sun::star::uno::XComponentContext Context )
+        raises (com::sun::star::uno::Exception);
+};
+
+}; }; }; };
+</pre>
+          </td>
+        </tr>
+      </table>
+      <ol>
+		<li><p>The callee of <code>createInstanceWithContext()</code> will
+		    prepare a context with its current one (that it is running on) as
+		    described here:
+		  </p>
+          <table width="100%" bgcolor="#ffffaa">
+            <tr>
+              <td>
+                <pre>
+any getValueByName( [in] string Name )
+{
+    if (new_properties.hasElement( Name ))
+    {
+        return new_properties.getElement( Name );
+    }
+    else
+    {
+        return factory_context.getValueByName( Name );
+    }
+}
+</pre>
+              </td>
+            </tr>
+          </table>
+        </li>
+        <li><p>The component factory's method <code>createInstanceWithContext()</code>
+          is called with the new context.</p>
+        </li>
+		<li><p>The component factory directly instantiates a component
+		   forwarding the context to use.</p></li>
+      </ol>
+      <p><i>Backward Compatibility: </i>If the user is calling <code>XMultiServiceFactory::createInstance()</code>
+        (old), then the service manager's context is provided to <code>XSingleComponentFactory::createInstanceWithContext()</code>.</p>
+	  <p>The service manager is the only instance that is used by older component implementations,
+        thus it is the only instance that knows the context to be propagated to
+        further component instances (implicitly calling old <code>XSingleServiceFactory::createInstance()</code>).
+	  This is a potential problem, because the only solution for proper context
+	  propagation would be to clone the service manager and install the new context;
+	although, one-instance component implementation (using static initializers)
+	will fatally hinder the propagation of the correct context.</p>
+	<p>For performance reasons, the current stoc service manager implementation does <b>not</b> clone <!-- xxx todo: will be implemented-->
+	the service manager in case of an <code>XSingleComponentFactory::createInstanceWithContext()</code> call.
+	This means that only directly launched service instances get the correct context.
+	In most cases, this should be no problem, because all up-to-date component implementations using component context
+	entries will call on <code>XSingleComponentFactory</code>, from entry-point service
+	objects to back-end service objects.
+      </p>
+<!--      <p><i><font color="#ff0000">What will be done, if a
+        context is given calling <code>createInstanceWithContext()</code> but
+        the component factory does not provide <code>XComponentFactory</code>?</font>:</i>
+        I propose throwing an exception, e.g. a <code>CannotActivateComponentException</code>,
+        because the component does not support context initialization.
+      </p>
+      -->
+
+<h2 id="current_context"> Current Context </h2>
+
+	<p>The dynamic context, also known as &quot;Current Context&quot;, is bound
+	   to the current execution task. A task denotes not only a process thread
+	   of execution, but the current context of a task remains for dispatched
+	   threads or inter-process invocation threads, for instance, a child
+	   thread inherits its initial current context from its parent thread.</p>
+	<p>The current context can be accessed via the UNO runtime which is part of
+	   the
+      <a href="../concept/uno_langbind.html#langspec">language binding specification</a>.
+      The runtime grants read access to the current context as well as installing
+      a different context for subsequent callers.
+      There is
+      <a href="http://wiki.services.openoffice.org/wiki/Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#Setting.2F_Retrieving_the_Current_Context">support for C/C++ by the <code>cppu</code> runtime</a> and the Java UNO runtime, although currently the context is not bridged.
+      The current context's interface is
+      <a href="http://api.openoffice.org/common/ref/com/sun/star/uno/XCurrentContext.html"><code>com.sun.star.uno.XCurrentContext</code></a>:
+      </p>
+      <table width="100%" bgcolor="#ffffaa">
+        <tr>
+          <td>
+            <pre>
+module com { module sun { module star { module uno {
+
+interface XCurrentContext : com::sun::star::uno::XInterface
+{
+    any getValueByName( [in] string Name );
+};
+
+}; }; }; };
+</pre>
+          </td>
+        </tr>
+      </table>
+
+      <p>It is always recommended to use an interface method to pass parameters,
+      due to explicit passing and type safety of parameters (caller's and
+      callee's contract). Though there are very few sensible cases for a current
+      context, common properties of the context are:</p>
+      <ul>
+        <li><p><b>access control restriction ("access-control.restriction") :
+	     <code>type com.sun.star.security.XAccessControlContext</code></b></p>
+		 <p>This property provides a task-local access control restriction
+		 taken into account during permission checks.  For details, have a look
+		 at <a href="uno_security.html#dynamic_restrictions">the dynamic
+		 restrictions</a> section of the security document.</p>
+	</li>
+	<li><p><b>access control user credentials ("access-control.user-credentials.*")</b></p>
+		<p>These properties relate to the calling user, e.g.
+		<code>access-control.user-credentials.id</code>.  For details, have a
+		look at <a href="uno_security.html#dynamic_restrictions">the dynamic
+		restrictions</a> section of the security document.</p>
+	</li>
+    <li><p>arbitrary values for higher stack levels which occur in an
+		  "optional" manner (could be described as "nice to have if set at the
+		  current context") like callback/ error handlers.</p>
+        </li>
+      </ul>
+	  <p>The current context interface reference must not be shared with other
+	  threads.
+      In general, you should also take care to not share values you got from the
+      current context with other threads.</p>
+	  <p>When calling across process boundaries, there is a question of what
+	  happens to
+      the dynamic context. Of course, remote transparency is a wishful feature.
+      On the other hand, remote access on the context has to be optimized for 
+      performance.</p>
+
+<!--        <i><font color="#ff0000">Open</font>:</i> Security and inter process
+        calls?<br/>
+        I propose that security relevant properties like the AccessController or
+	the authenticated Subject are not
+	transmitted, because this leads to a potential security hole (refer to
+	<a href="uno_security.html#remote">security draft</a>).<br/>
+      A process for handling this via remote may be establishing a lasting authentication
+      (over multiple calls) for a user. A previous authentication process (including
+      password dialogs, etc.) will establish a ticket on both sides (aka secure
+      association). This ticket builds up the subject. When transferring via remote,
+      only the ticket is transferred, then any authorization has to be performed
+      on the (locally authenticated) user's behalf. <br/>
+-->
+
+<h2 id="component_descr"> Extensions to the XML Component Description </h2>
+
+<p>In this section, I propose extensions to the current <a href="http://udk.openoffice.org/common/man/module_description.html">XML
+        component description</a> describing deployment properties of a component
+        implementation and invariants.
+	Invariants allow testing of a specific deployment, that is, if the specific values
+	make sense.
+        All elements appear as sub element of <code>component-description</code> which, now, may
+        also contain a <code>component-properties</code> element:</p>
+
+      <table width="100%" bgcolor="#ffffaa">
+        <tr>
+          <td>
+            <pre>
+&lt;!ELEMENT component-description
+          (author,name,description,loader-name,supported-service+,
+           <b>component-properties?</b>,(%component-description-optional;)*)&gt;
+
+&lt;!ELEMENT component-properties property*&gt;
+&lt;!ELEMENT property description? invariant*&gt;
+&lt;!ATTLIST property name CDATA #REQUIRED
+                   optional (true|false) #IMPLIED
+                   value-type (boolean|string|number) #IMPLIED
+                   default-value CDATA #IMPLIED&gt;
+
+&lt;!ELEMENT invariant EMPTY&gt;
+&lt;!ATTLIST invariant type (valid|invalid|min|max) #REQUIRED
+                    value CDATA #IMPLIED&gt;
+</pre>
+          </td>
+        </tr>
+      </table>
+
+	  <p>Properties are described by their <code>name</code>,
+	  <code>value-type</code>, <code>optional</code> attributes, and a number
+	  of optional <code>invariant</code>s.  The <code>name</code> denotes the
+	  property's name as it will appear in contexts.  The <code>optional</code>
+	  attribute denotes whether the property can optionally
+	  be set in a deployment or is mandatory (i.e. if not set, the component
+	  implementation
+      cannot run).  An optional <code>default-value</code> can also be set.
+      Invariants follow up as sub elements
+	  to check whether a given property value makes sense. The invariants given
+	  <code>value</code>
+      must always be convertible to the property's <code>value-type</code>.</p>
+	  <p>Current invariant <code>type</code>s have been chosen for the
+	  following strings:</p>
+      <ul>
+      <li><code>valid</code> -- denotes a valid value of the property overriding all other invariants</li>
+      <li><code>invalid</code> -- denotes an invalid value of the property overriding all other invariants except the
+      <code>valid</code> invariant</li>
+      <li><code>min</code> -- denotes a lower boundary for a property number value</li>
+      <li><code>max</code> -- denotes a upper boundary for a property number value</li>
+      </ul>
+
+      <p>Example:</p>
+      <table width="100%" bgcolor="#ffffaa">
+        <tr>
+          <td>
+            <pre>
+...
+&lt;component-properties&gt;
+ &lt;property name="DataProvider1.CacheOn" value-type="boolean"/&gt;
+ &lt;property name="DataProvider1.CacheSize" value-type="number" default-value="256"&gt;
+  &lt;invariant type="min" value="128"/&gt;
+  &lt;invariant type="max" value="512"/&gt;
+  &lt;description&gt;
+  Property CacheOn controls whether caching of data should be performed.
+  Property CacheSize controls the size of the cache.  The CacheSize is limited to a range
+  between 128 and 512.
+  &lt;/description&gt;
+ &lt;/property&gt;
+&lt;/component-properties&gt;
+...
+</pre>
+          </td>
+        </tr>
+      </table>
+
+      <p>
+      <i><font color="#ff0000">Attention: Proposal only!</font></i>
+      The previous component description extensions
+      are yet to be discussed and extended -- and implemented -- 
+      with respect to further tools performing tests.
+      </p>
+
+<h2 id="oneinstance"> Migration path for existing OneInstance services </h2>
+
+<p>Formerly, a service decided to be a one instance service by choosing the appropriate factory
+( in general cppu::createOneInstanceFactory() ). When the service is first instantiated,
+the factory keeps a hard reference to the service. All subsequent createInstance()-calls
+return the same object. When the servicemanager got disposed, it disposed all factories,
+which released the reference.
+
+<p> The former OneInstance services can be separated into the following categories :
+
+<ol>
+<li><p>Services that have state or instantiate other services.</p></li>
+<li><p>Services that don't have state and that don't instantiate further
+     services.
+     These services are OneInstance for optimization reasons
+     ( it would be a waste of heap to have multiple instances).
+	 A classical example is the TypeConverter services, which offers simple
+	 conversion functions.
+   </p></li>
+</ol>
+
+Each group must be treated differently when moving to the context concept.
+
+<ol>
+<li><p>These are
+<a href="#singleton">singletons</a>.
+These objects should be placed into the context.
+You use a normal factory, so that it is possible to instantiate multiple instances.
+You add a singleton entry to the idl-file. All clients, that previously accessed the object
+via the servicemanager, must switch to accessing it via a context. This is a required change.
+</p>
+<p> If there is not time to make the changes immediately, then stick to the OneInstance
+service, as it is currently, and schedule a task force for it.
+</p>
+
+<p> There may be exceptions, for instance, the javavm service can only be started once per process and
+    it must not die (because the javavm can not be released once it has been started).
+	Such conditions should be handled by the component internally, that is, the javavm-service
+	will hold its self or it will keep a list of the contexts it is used in, and adds itself as
+	disposing listeners. These exceptions should be really rare !
+	</p>
+
+<p> Another possibility may be to make it a normal service.</p>
+
+<li><p>These services can be reused over all contexts, so a single instance per
+process is
+desired. These services should use a normal factory, but within the dll-local createInstance()
+function, they keep a static weak reference on the object. For every createInstance()-call,
+it first checks the weak reference. Otherwise, it instantiates the implementation and assigns
+it to the weak reference.
+</p></li>
+</ol>
+
+<h2 id="registries"> Registry considerations for context-information </h2>
+<p>The following deployment issues arise when introducing contexts:</p>
+
+<ol>
+<li><p>There is need for a place to store the singleton information (i.e. the
+     name of the service
+     to be instantiated when a singleton gets accessed the first time).</p></li>
+<li><p>There is need for a place to store implementation-dependent context settings.</p></li>
+</ol>
+
+<h4>Singleton</h4>
+<p>A singleton gets a service-name assigned in an idl-file (which means at
+specification time). For example, the com.sun.star.theBridgeFactory-singleton
+is assigned to the com.sun.star.bridge.BridgeFactory service and can be
+instantiated at runtime using this name.</p>
+<p>But the specification in idl is only minimal, the singleton instance must,
+<b>at least</b>, support this service. Take a look at the service-manager;
+something that we call a service-manager must at least support the
+
+<a href="http://api.openoffice.org/common/ref/com/sun/star/lang/MulitServiceFactory.html">
+com.sun.star.lang.MultiServiceFactory</a>
+
+service, so this is specified in IDL. However, in OpenOffice.org, we need a
+<a href="http://api.openoffice.org/common/ref/com/sun/star/lang/RegistryServiceFactory.html">
+com.sun.star.lang.RegistryServiceFactory</a>
+service, which additionally supports the MultiServiceFactory.
+This information can't be retrieved from IDL anymore, it must be defined at
+deployment time.</p>
+
+<p>
+The initial routine, that creates the context, must be able to access the
+singleton-information.  This information should be provided in an .rdb-file
+(the only persistent storage we have on the UDK-level).  The following kinds of
+information is currently stored in an .rdb-file:</p>
+
+<ol>
+<li><p>Types (needed by the typeprovider),</p></li>
+<li><p>Service registrations (needed by the RegistryServiceManager),</li>
+<li><p>Singleton information (needed by the initial routine that creates the
+context).</p></li>
+</ol>
+
+<p>I think a good strategy is to have one .rdb-file for each category. This
+avoids unnecessary nesting of registries and gives the most flexibility when
+multiple processes shall share registries (though it always needs to be taken
+into account that a registry can only be opened with write access, when no
+other process have read or write access to the same registry). To reflect this,
+we should introduce the following bootstrap-variables :</p>
+
+<ul>
+<li><p>UNO_TYPESRDB    (contains a list of registry-names that contain type information
+                      [read-only-access])</p></li>
+<li><p>UNO_SERVICESRDB (contains a list of registry-names that contain the registered services
+                      [read-only-access])</p></li>
+<li><p>UNO_CONTEXTRDB  (contains a list of registry-names that contain the singleton-information
+                      [read-only-access])</p></li>
+<li><p>UNO_SERVICESRDB_RW (contains exactly one registry name where service information
+                      can be written)</p></li>
+</ul>
+
+Note that you still can have one registry, that holds all information (types,services, and contexts).
+This registry would get opened three times, which bears no problem as long as it is
+opened for read only.
+
+<h4>Additional context settings</h4>
+<p>The context contains (besides singletons) component specific values. This
+information
+must be available when the context is created, so, it seems a good idea to insert this information
+into the above suggested .rdb-file.</p>
+
+<p> The registry does not offer to store all possible UNO-types, since it must store the value as
+a byte-sequence ( with some routines such as any2Sequence() and sequence2Any() in cppu).</p>
+
+<p> There needs to be a command line-tool, that inserts values into a rdb.</p>
+
+<h4>Integration into the build process</h4>
+<p>There is no comprehensive solution-suggestion currently, so here are listed
+some thoughts.</p>
+
+<ul>
+<li><p>The singleton-information specified in IDL must be available outside
+	 udkapi/offapi project.  This should be delivered as its own .rdb-file
+	 (maybe udk_singleton.rdb).</p></li>
+<li><p>If we come to the conclusion
+	 that the creation of the service-manager will probably always be hardcoded, it should be
+	 sufficient, currently, for most tools not to have a context .rdb-file.</p></li>
+<li><p>How do we get a context.rdb for an application? The knowledge on what
+     should be in the
+     context.rdb is distributed.</p>
+	 <ul>
+	 <li> The component developer wants to give some sensible defaults to context values.
+	 <li> At the time the setup for a certain application is built, one wants to insert
+	      only those context values that could be needed in the deployed application.
+		  Here it will be very difficult to avoid redundancies for multiple applications.
+     <li> The setup wants to install only context values for installed components and it
+	      wants to omit other ones.
+     <li> The user/deployer wants to modify or add context values.
+	 </ul>
+
+</ul>
+
+<h4>Registry limitations</h4>
+<p>A lot of deployment problems arise from storing information into an
+.rdb-file. We definitely need a database in core UNO as soon as possible.
+It is planned to use the configuration services for this and to move component
+registration into it.  This will ease getting overviews about components,
+implementations, properties, singletons, location, et cetera.
+Registry database files (rdb) are only used for type access.</p>
+<p>The coming structure of the configuration (which is read-only accessible via
+the component context) will look like this:</p>
+
+<table width="100%" bgcolor="#ffffaa"><tr><td><pre>
+/singletons/theFoobar/
+    service = Foobar
+    [arguments = { ... }]
+...
+
+/services/Foobar/
+    available-implementations = { FbImpl[, ...] }
+    uses-implementation = FbImpl
+    [&lt;arbitrary conceptional properties&gt;]
+...
+
+/implementations/FbImpl/
+    supports-services = { Foobar[, ...] }
+    url = libfoobar.so
+    activator = com.sun.star.loader.SharedLibrary
+    [&lt;arbitrary properties&gt;]
+...
+</pre></td></tr></table>
+<p>
+<em>
+(last two sections co-edited by <a href="mailto:joerg.budischewski@sun.com">Joerg
+Budischewski</a>.)</em></p>
+
+<h2 id="todos">Things left to do... </h2>
+
+<p>The following things are left to do:</p>
+
+<ul>
+<li><p><b>[high priority]: </b>
+There is currently no persistent storage for component context values,
+singleton object specifications, services, and implementations.  This includes
+switching service registration to this storage format.</p>
+<p>We have to use the configuration services as soon as possible, that is,
+bring configuration into UDK.</p>
+</li>
+<li><p><b>[mid priority]: </b>
+Supporting <code>XMultiServiceFactory</code> the service manager has to be
+revisited.  The service manager has to clone itself (changes
+<code>DefaultContext</code> property) when a
+<code>createInstanceWithContext</code> changes the context of the component to
+be raised.</p>
+</li>
+<li><p><b>[low priority]: </b>
+The current context is not transferred via the URP-UNO interprocess bridge.
+This has to be fixed with no lack of performance.</p>
+</li>
+</ul>
+<table width=100% summary="Footer">
+<tr>
+<td bgcolor="#666699">
+ <p><font color="#ffffff"> Author: <a href="mailto:Daniel.Boelzle@sun.com">
+<font color="#ffffff">Daniel B&ouml;lzle</font></a><br/>
+  <i>Copyright 2001 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, CA 94303 USA.</i></font
+</p>
+</td>
+</tr>
+</table>
+</body>
+</html>

Propchange: incubator/ooo/ooo-site/trunk/content/udk/common/man/concept/uno_contexts.html
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message