You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ks...@apache.org on 2011/11/27 23:36:59 UTC
svn commit: r1206884 [1/4] - in
/incubator/ooo/ooo-site/trunk/content/ucb/docs: ./ ucp-ref/
Author: kschenk
Date: Sun Nov 27 22:36:56 2011
New Revision: 1206884
URL: http://svn.apache.org/viewvc?rev=1206884&view=rev
Log:
kls -- added ucb/docs
Added:
incubator/ooo/ooo-site/trunk/content/ucb/docs/
incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucb-api-usage.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucb-configuration.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucb-overview.odp (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/file-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/ftp-contents.gif (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/ftp-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/help-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/hierarchy-contents.gif (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/hierarchy-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/odma-ucp.gif (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/odma-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/package-contents.gif (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/package-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/tdoc-contents.gif (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/tdoc-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/webdav-contents.gif (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/webdav-ucp.html (with props)
incubator/ooo/ooo-site/trunk/content/ucb/docs/ucp-ref/wfs.gif (with props)
Added: incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html
URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html?rev=1206884&view=auto
==============================================================================
--- incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html (added)
+++ incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html Sun Nov 27 22:36:56 2011
@@ -0,0 +1,1017 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
+ <TITLE>Cachemaps</TITLE>
+ <STYLE>
+ <!--
+ A:link { color: #444488 }
+ A:visited { color: #444488 }
+ -->
+ </STYLE>
+</HEAD>
+<BODY LINK="#444488" VLINK="#444488">
+<TABLE WIDTH=100% BORDER=0 CELLPADDING=4 CELLSPACING=0 STYLE="page-break-before: always">
+ <COL WIDTH=75>
+ <TR>
+ <TD BGCOLOR="#666699">
+ <H1 ALIGN=CENTER STYLE="margin-top: 0cm; text-decoration: none"><A HREF="http://www.openoffice.org/"><IMG SRC="../images/open_office_org_logo.gif" NAME="Graphic1" ALT="OpenOffice.org" ALIGN=RIGHT WIDTH=126 HEIGHT=53 BORDER=0></A><FONT COLOR="#ffffff"><FONT SIZE=6>Cachemaps</FONT></FONT></H1>
+ </TD>
+ </TR>
+</TABLE>
+<HR SIZE=3 NOSHADE>
+<TABLE WIDTH=100% BORDER=0 CELLPADDING=4 CELLSPACING=0 STYLE="page-break-before: always">
+ <COL WIDTH=256*>
+ <TR>
+ <TD WIDTH=100% BGCOLOR="#666699">
+ <H3 ALIGN=LEFT STYLE="margin-top: 0cm; text-decoration: none"><FONT COLOR="#ffffff"><FONT SIZE=4>Contents</FONT></FONT></H3>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0cm"><A HREF="#Abstract">Abstract</A><BR>
+ <A HREF="#Solution1">Solution 1 (Single Mutex)</A><BR>
+ <A HREF="#Solution2">Solution 2 (Weak References)</A><BR>
+ <A HREF="#Solution3">Solution 3 (Best of Both Worlds)</A><BR>
+ <A HREF="#Measurements">Performance Measurements</A></P>
+ <P><BR></P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100% BGCOLOR="#666699">
+ <H3 ALIGN=LEFT STYLE="margin-top: 0cm; text-decoration: none"><A NAME="Abstract"></A>
+ <FONT COLOR="#ffffff"><FONT SIZE=4>Abstract</FONT></FONT></H3>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">I quite often have the need for a construct I will call a
+ <I>cachemap.</I> A cachemap is like an ordinary map (or hashmap), in
+ that it maps from keys (normally strings) to objects, but it also
+ controls the lifetime of the mapped objects. If a client requests an
+ object that is not yet instantiated, a (refcounted) instance is
+ created, inserted into the cachemap, and returned to the client. If
+ the client no longer needs the object (the refcount of the object
+ drops to zero), it is automatically removed from the cachemap. And if
+ a client requests an object that is already present in the cachemap
+ (because it was requested by a client before, and its refcount is
+ still positive), the present instance is returned. Skeleton C++ class
+ definitions for the cachemap and the objects it manages could look
+ like the following:</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>class ObjectContainer // the cachemap
+{
+public:
+ rtl::Reference< Object > get(rtl::OUString const & rKey);
+};
+
+class Object // the objects managed by the cachemap
+{
+public:
+ void acquire() SAL_THROW(());
+
+ void release() SAL_THROW(());
+};</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">The problems in implementing this are that (1) the cachemap must not
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">acquire()</FONT></FONT>
+ the objects it currently has in its map (otherwise, the refcounts of
+ those objects could never drop to zero, and they would never be
+ removed from the map), and (2) in a multi-threaded environment there
+ is a problem when one thread does a final <FONT SIZE=2><FONT FACE="Courier New, monospace">release()</FONT></FONT>
+ of an object (refcount drops to zero and object is removed from the
+ map) and at the same time another thread happens to call <FONT SIZE=2><FONT FACE="Courier New, monospace">get()</FONT></FONT>
+ to request that very object.</P>
+ <P STYLE="margin-bottom: 0.1cm">Below, I describe three different implementations that solve these
+ problems. The first solution was my initial idea, but it tends to be
+ slow. The second is based on weak references, but it turned out to be
+ slow, too. The third combines ideas from the other two
+ solutions---and it turned out to be fast. So, if you are interested
+ in boiler plate code for a fast implementation of the cachemap
+ pattern, turn to <A HREF="#Solution3">the third solution</A>
+ directly.</P>
+ <P STYLE="margin-bottom: 0.1cm">The three solutions all follow the same conventions. They
+ implement an <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer<I>N</I></FONT></FONT>
+ (the cachemap, mapping from strings to objects) and a corresponding
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">Object<I>N</I></FONT></FONT>
+ (the refcounted objects managed by the cachemap). The source code
+ presented here is also available within the ucb project
+ (<A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/"><FONT SIZE=2><FONT FACE="Courier New, monospace">ucb/workben/cachemap</FONT></FONT></A>),
+ and it is presented here without the (somewhat longish) copyright
+ headers.</P>
+ <P ALIGN=LEFT><BR></P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100% BGCOLOR="#666699">
+ <H3 ALIGN=LEFT STYLE="margin-top: 0cm; text-decoration: none"><A NAME="Solution1"></A>
+ <FONT COLOR="#ffffff"><FONT SIZE=4>Solution 1 (Single Mutex)</FONT></FONT></H3>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">The
+ combined header file for both <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>
+ and <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT> is
+ <A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemapobject1.hxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemapobject1.hxx</FONT></FONT></A>:</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>#ifndef <A HREF="#validguardnames">INCLUDED_UCB_CACHEMAPOBJECT1_HXX</A>
+#define INCLUDED_UCB_CACHEMAPOBJECT1_HXX
+
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _SAL_TYPES_H_
+#include "sal/types.h"
+#endif
+#ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_
+#include "salhelper/simplereferenceobject.hxx"
+#endif
+
+#ifndef <A HREF="#stdguards">INCLUDED_MAP</A>
+#include <map>
+#define INCLUDED_MAP
+#endif
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace rtl { class OUString; }
+namespace ucb { namespace cachemap { class Object1; } }
+
+namespace ucb { namespace cachemap {
+
+class ObjectContainer1: <A HREF="#refcountedcontainer">public salhelper::SimpleReferenceObject</A>
+{
+public:
+ ObjectContainer1();
+
+ virtual ~ObjectContainer1() SAL_THROW(());
+
+ rtl::Reference< Object1 > get(rtl::OUString const & rKey);
+
+private:
+ typedef <A HREF="#map">std::map</A>< rtl::OUString, Object1 * > Map;
+
+ Map m_aMap;
+ osl::Mutex m_aMutex;
+
+ void releaseElement(Object1 * pElement) SAL_THROW(());
+
+ <A HREF="#friends">friend class Object1;</A> // to access Map, releaseElement()
+};
+
+class Object1
+{
+public:
+ inline void acquire() SAL_THROW(())
+ { osl_incrementInterlockedCount(&m_nRefCount); }
+
+ inline void release() SAL_THROW(())
+ { m_xContainer->releaseElement(this); }
+
+private:
+ rtl::Reference< ObjectContainer1 > m_xContainer;
+ ObjectContainer1::Map::iterator m_aContainerIt;
+ oslInterlockedCount m_nRefCount;
+
+ inline Object1(rtl::Reference< ObjectContainer1 > const & rContainer);
+
+ inline ~Object1() SAL_THROW(());
+
+ Object1(Object1 &); // not implemented
+ void operator =(Object1); // not implemented
+
+ friend class ObjectContainer1;
+ // to access m_aContainerIt, m_nRefCount, Object1(), ~Object1()
+#if defined WNT
+ friend struct std::auto_ptr< Object1 > // to access ~Object
+ // work around compiler bug...
+#else // WNT
+ <A HREF="#autoptrfriend">friend class std::auto_ptr< Object1 >;</A> // to access ~Object1()
+#endif // WNT
+};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECT1_HXX</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">A few notes:</P>
+ <UL>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="validguardnames"></A>It is a good idea to use valid
+ C++ identifiers as include guards for header files. That is, do not
+ use identifiers that start with an underline followed by an upper
+ case letter (e.g., <FONT SIZE=2><FONT FACE="Courier New, monospace">_UCB_CACHEMAPOBJECT1_HXX_</FONT></FONT>)
+ or that contain two underlines in a row, because those identifiers
+ are reserved for internal use by the compiler and standard library
+ implementation. (<A HREF="http://cseng.aw.com/book/0,,0201633620,00.html">Lakos</A>,
+ section 2.4, suggestes the <FONT SIZE=2><FONT FACE="Courier New, monospace">INCLUDED_<I>XXX</I></FONT></FONT>
+ style.)</P>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="stdguards"></A>Use the convention of (redundant but
+ compilation time reducing) external include guards for standard
+ header files, too. For this to work, it is necessary that everybody
+ use the same identifiers for the various standard header files, of
+ course. (See <A HREF="http://cseng.aw.com/book/0,,0201633620,00.html">Lakos</A>,
+ section 2.5.)</P>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="refcountedcontainer"></A><FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>
+ turns out to be a refcounted object. This was not required in the
+ introduction of the cachemap pattern, but it is rather a consequence
+ of the chosen implementation (and it should not hurt any client,
+ either).</P>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="map"></A>In <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>,
+ a <FONT SIZE=2><FONT FACE="Courier New, monospace">std::map</FONT></FONT>
+ is used instead of a (de facto standard?) <FONT SIZE=2><FONT FACE="Courier New, monospace">std::hash_map</FONT></FONT>
+ that might be a bit faster. The implementation of <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>
+ relies on the fact that iterators into a <FONT SIZE=2><FONT FACE="Courier New, monospace">std::map</FONT></FONT>
+ are not invalidated when calling <FONT SIZE=2><FONT FACE="Courier New, monospace">insert()</FONT></FONT>
+ or <FONT SIZE=2><FONT FACE="Courier New, monospace">erase()</FONT></FONT>.
+ There seems to be no corresponding guarantee for <FONT SIZE=2><FONT FACE="Courier New, monospace">std::hash_map</FONT></FONT>.</P>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="friends"></A><FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>
+ and <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>
+ need to be mutual friends. If one entity is a friend of another,
+ these entities are strongly coupled, and it seems always best to
+ keep them together in a single header file (thereby breaking the
+ rule to have a seperate header file for each class).</P>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="autoptrfriend"></A>Logically, only <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>
+ is allowed to create and destroy instances of <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>,
+ hence the design decision to make the constructor and destructor of
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>
+ private and make <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>
+ a friend of <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>.
+ But a <FONT SIZE=2><FONT FACE="Courier New, monospace">std::auto_ptr<
+ Object1 ></FONT></FONT> is needed at one place in the
+ implementation, and that <FONT SIZE=2><FONT FACE="Courier New, monospace">std::auto_ptr</FONT></FONT>
+ also needs access to the destructor of <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>.
+ It seemed best to simply make <FONT SIZE=2><FONT FACE="Courier New, monospace">std::auto_ptr<
+ Object1 ></FONT></FONT> a friend of <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>,
+ too, in this situation (though too many friends can be an indication
+ of bad design.) Alas, the Microsoft compiler used on the Windows x86 platform
+ (<FONT SIZE=2><FONT FACE="Courier New, monospace">WNT</FONT></FONT> define)
+ needs to see <FONT SIZE=2><FONT FACE="Courier New, monospace">struct</FONT></FONT> (or nothing) in this friend declaration,
+ instead of the correct <FONT SIZE=2><FONT FACE="Courier New, monospace">class</FONT></FONT>, so some
+ platform-dependent code is needed here (and in retrospect it might seem better to make the destructor of
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT> public and get rid of all this).</P>
+ </UL>
+ <P STYLE="margin-bottom: 0.1cm">The corresponding implementation file is
+ <A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemapobject1.cxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemapobject1.cxx</FONT></FONT></A>:</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>#ifndef INCLUDED_UCB_CACHEMAPOBJECT1_HXX
+<A HREF="#orderofincludes">#include "cachemapobject1.hxx"</A>
+#endif
+
+#ifndef _OSL_DIAGNOSE_H_
+#include "osl/diagnose.h"
+#endif
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include "rtl/ustring.hxx"
+#endif
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+using ucb::cachemap::Object1;
+using ucb::cachemap::ObjectContainer1;
+
+inline
+Object1::Object1(rtl::Reference< ObjectContainer1 > const & rContainer):
+ m_xContainer(rContainer),
+ m_nRefCount(0)
+{
+ OSL_ASSERT(m_xContainer.is());
+}
+
+inline Object1::~Object1() SAL_THROW(())
+{}
+
+void ObjectContainer1::releaseElement(Object1 * pElement) SAL_THROW(())
+{
+ OSL_ASSERT(pElement);
+ bool bDelete = false;
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ if (osl_decrementInterlockedCount(&pElement->m_nRefCount) == 0)
+ {
+ m_aMap.erase(pElement->m_aContainerIt);
+ bDelete = true;
+ }
+ }
+ <A HREF="#minimalmutex">if (bDelete)</A>
+ delete pElement;
+}
+
+ObjectContainer1::ObjectContainer1()
+{}
+
+ObjectContainer1::~ObjectContainer1() SAL_THROW(())
+{}
+
+rtl::Reference< Object1 > ObjectContainer1::get(rtl::OUString const & rKey)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ Map::iterator aIt(m_aMap.find(rKey));
+ if (aIt == m_aMap.end())
+ {
+ <A HREF="#autoptr">std::auto_ptr< Object1 ></A> xElement(new Object1(this));
+ aIt = m_aMap.insert(Map::value_type(rKey, xElement.get())).first;
+ aIt->second->m_aContainerIt = aIt;
+ xElement.release();
+ }
+ return aIt->second;
+}</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <UL>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="orderofincludes"></A>It is always a good idea to
+ include the header file that belongs to an implementation file first
+ in that file. That way, there is an automatic check that each header
+ file is self-contained (for almost every header, there is a
+ corresponding implementation file, and compilation of that file
+ fails if the header is not self-contained). (See <A HREF="http://cseng.aw.com/book/0,,0201633620,00.html">Lakos</A>,
+ section 3.2.)</P>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="minimalmutex"></A>Note how <FONT SIZE=2><FONT FACE="Courier New, monospace">releaseElement()</FONT></FONT>
+ deletes the element only after the mutex has been released. It is
+ good practice to do as little as absolutely necessary during the
+ time a mutex is locked.</P>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="autoptr"></A>Note how a <FONT SIZE=2><FONT FACE="Courier New, monospace">std::auto_ptr<
+ Object1 ></FONT></FONT> is used to ensure the newly created
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>
+ is properly deleted in case the <FONT SIZE=2><FONT FACE="Courier New, monospace">insert()</FONT></FONT>
+ happens to throw an exception.</P>
+ </UL>
+ <P STYLE="margin-bottom: 0.1cm">The way the problems mentionend in the introduction are solved
+ here is that <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>
+ only holds pointers to instances of <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1</FONT></FONT>,
+ not refcounting references, and that <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1::release()</FONT></FONT>
+ is simply forwarded to <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1::releaseElement()</FONT></FONT>.
+ The <FONT SIZE=2><FONT FACE="Courier New, monospace">releaseElement()</FONT></FONT>
+ method checks whether the refcount of the object drops to zero and
+ removes it from the map, if appropriate. The methods
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1::releaseElement()</FONT></FONT>
+ and <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1::get()</FONT></FONT>
+ share a mutex, so that there can never be the situation that one
+ thread tries to get an object another thread is about to delete. The
+ disadvantage of this solution is that every call to
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">Object1::release()</FONT></FONT>
+ needs to acquire a mutex, which is quite expensive on typical
+ platforms.</P>
+ <P ALIGN=LEFT><BR></P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100% BGCOLOR="#666699">
+ <H3 ALIGN=LEFT STYLE="margin-top: 0cm; text-decoration: none"><A NAME="Solution2"></A>
+ <FONT COLOR="#ffffff"><FONT SIZE=4>Solution 2 (Weak References)</FONT></FONT></H3>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">The UNO concept of weak references offers itself as another
+ solution to the problem: <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer2</FONT></FONT>
+ holds weak references to instances of <FONT SIZE=2><FONT FACE="Courier New, monospace">Object2</FONT></FONT>,
+ and the mechanism used in the <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer2::get()</FONT></FONT>
+ method to translate a weak reference to an <FONT SIZE=2><FONT FACE="Courier New, monospace">Object2</FONT></FONT>
+ into a hard reference (that may then turn out to be null) solves all
+ the problems for us.</P>
+ <P STYLE="margin-bottom: 0.1cm">With this solution, only <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer2</FONT></FONT>
+ needs to know <FONT SIZE=2><FONT FACE="Courier New, monospace">Object2</FONT></FONT>,
+ and not also the other way around (as it was in the first solution
+ due to the mutual friend-ness of the two classes). Therefore, there
+ are individual header files for <FONT SIZE=2><FONT FACE="Courier New, monospace">Object2</FONT></FONT>
+ and <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer2</FONT></FONT>.</P>
+ <P STYLE="margin-bottom: 0.1cm">The header file
+ <A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemapobject2.hxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemapobject2.hxx</FONT></FONT></A>
+ is nothing more than a skeleton (<FONT SIZE=2><FONT FACE="Courier New, monospace">Object2</FONT></FONT>
+ is so bare-bones it does not even need an implementation file):</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>#ifndef INCLUDED_UCB_CACHEMAPOBJECT2_HXX
+#define INCLUDED_UCB_CACHEMAPOBJECT2_HXX
+
+#ifndef _CPPUHELPER_WEAK_HXX_
+#include "cppuhelper/weak.hxx"
+#endif
+
+namespace ucb { namespace cachemap {
+
+class Object2: public cppu::OWeakObject
+{};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECT2_HXX</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">The header file
+ <A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemapobjectcontainer2.hxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemapobjectcontainer2.hxx</FONT></FONT></A>
+ is hardly more interesting:</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>#ifndef INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX
+#define INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX
+
+#ifndef _CPPUHELPER_WEAKREF_HXX_
+#include "cppuhelper/weakref.hxx"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _SAL_TYPES_H_
+#include "sal/types.h"
+#endif
+
+#ifndef INCLUDED_HASH_MAP
+#include <hash_map>
+#define INCLUDED_HASH_MAP
+#endif
+
+namespace rtl {
+ class OUString;
+ struct OUStringHash;
+}
+namespace ucb { namespace cachemap { class Object2; } }
+
+namespace ucb { namespace cachemap {
+
+class ObjectContainer2
+{
+public:
+ ObjectContainer2();
+
+ ~ObjectContainer2() SAL_THROW(());
+
+ rtl::Reference< Object2 > get(rtl::OUString const & rKey);
+
+private:
+ typedef <A HREF="#hashmap">std::hash_map</A>< rtl::OUString,
+ com::sun::star::uno::WeakReference< Object2 >,
+ rtl::OUStringHash >
+ Map;
+
+ ObjectContainer2(ObjectContainer2 &); // not implemented
+ void operator =(ObjectContainer2); // not implemented
+
+ Map m_aMap;
+ osl::Mutex m_aMutex;
+};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <UL>
+ <LI><P STYLE="margin-bottom: 0.1cm"><A NAME="hashmap"></A>Here, a (de facto standard?)
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">std::hash_map</FONT></FONT>
+ is used instead of a <FONT SIZE=2><FONT FACE="Courier New, monospace">std::map</FONT></FONT>
+ as used for <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer1</FONT></FONT>:
+ We do not need any guarantees about iterators, so there is no reason
+ not to use the (potentially faster) <FONT SIZE=2><FONT FACE="Courier New, monospace">std::hash_map</FONT></FONT>.</P>
+ </UL>
+ <P STYLE="margin-bottom: 0.1cm">The solution to the implementation problems is hidden in the
+ implementation of <FONT SIZE=2><FONT FACE="Courier New, monospace">cppu::OWeakObject</FONT></FONT>
+ and <FONT SIZE=2><FONT FACE="Courier New, monospace">com::sun::star::uno::WeakReference</FONT></FONT>,
+ so the implementation file
+ <A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemapobjectcontainer2.cxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemapobjectcontainer2.cxx</FONT></FONT></A>
+ is quite simple, too:</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>#ifndef INCLUDED_UCB_CACHEMAPOBJECTCONTAINER2_HXX
+#include "cachemapobjectcontainer2.hxx"
+#endif
+
+#ifndef INCLUDED_UCB_CACHEMAPOBJECT2_HXX
+#include "cachemapobject2.hxx"
+#endif
+
+#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
+#include "com/sun/star/uno/Reference.hxx"
+#endif
+#ifndef _COM_SUN_STAR_UNO_XWEAK_HPP_
+#include "com/sun/star/uno/XWeak.hpp"
+#endif
+#ifndef _CPPUHELPER_WEAKREF_HXX_
+#include "cppuhelper/weakref.hxx"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include "rtl/ustring.hxx"
+#endif
+
+using namespace com::sun;
+using ucb::cachemap::Object2;
+using ucb::cachemap::ObjectContainer2;
+
+ObjectContainer2::ObjectContainer2()
+{}
+
+ObjectContainer2::~ObjectContainer2() SAL_THROW(())
+{}
+
+rtl::Reference< Object2 > ObjectContainer2::get(rtl::OUString const & rKey)
+{
+ rtl::Reference< Object2 > xElement;
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ Map::iterator aIt(m_aMap.find(rKey));
+ if (aIt != m_aMap.end())
+ xElement = static_cast< Object2 * >(
+ star::uno::Reference< star::uno::XWeak >(
+ aIt->second.get(), star::uno::UNO_QUERY).
+ get());
+ if (!xElement.is())
+ {
+ xElement = new Object2;
+ m_aMap[rKey]
+ = star::uno::WeakReference< Object2 >(xElement.get());
+ }
+ }
+ return xElement;
+}</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">The main trick (hack?) here is to translate from a
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">com::sun::star::uno::WeakReference<
+ Object2 ></FONT></FONT> via a <FONT SIZE=2><FONT FACE="Courier New, monospace">com::sun::star::uno::Reference<
+ com::sun::star::uno::XWeak ></FONT></FONT> to an <FONT SIZE=2><FONT FACE="Courier New, monospace">rtl::Reference<
+ Object2 ></FONT></FONT> (in general, you must go from a
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">com::sun::star::uno::WeakReference<
+ <I>T</I> ></FONT></FONT> to a <FONT SIZE=2><FONT FACE="Courier New, monospace">com::sun::star::uno::Reference<
+ <I>T</I> ></FONT></FONT>, but it is not possible to have a
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">com::sun::star::uno::Reference<
+ Object2 ></FONT></FONT>, so we must go via the base class <FONT SIZE=2><FONT FACE="Courier New, monospace">XWeak</FONT></FONT>
+ here).</P>
+ <P STYLE="margin-bottom: 0.1cm">The drawback of this solution is that it is not faster than the
+ initial one (even slower on some platforms). The overhead of using
+ the (generic) mechanism of weak references when requesting objects
+ outweights the benefits of the faster refcounting.</P>
+ <P STYLE="margin-bottom: 0.1cm">Another point that can well be a drawback of this solution is that
+ a weak reference to a destroyed object is not removed from the map;
+ it is replaced with a weak references to a living object the next
+ time <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer2::get()</FONT></FONT>
+ requests that object, but it is never erased from the map. Therefore,
+ the map itself keeps growing over the lifetime of the
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer2</FONT></FONT>
+ instance.</P>
+ <P ALIGN=LEFT><BR></P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100% BGCOLOR="#666699">
+ <H3 ALIGN=LEFT STYLE="margin-top: 0cm; text-decoration: none"><A NAME="Solution3"></A>
+ <FONT COLOR="#ffffff"><FONT SIZE=4>Solution 3 (Best of Both Worlds)</FONT></FONT></H3>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">If exploiting the generic facilities in the second solution did
+ not give any performance advantage, let us try to become faster with
+ a hand-crafted version (i.e, combining the hand-crafted framework of
+ the first solution with the implementation details of the second
+ one).</P>
+ <P STYLE="margin-bottom: 0.1cm">The header file
+ <A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemapobject3.hxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemapobject3.hxx</FONT></FONT></A>
+ is almost identical to the header file from the first solution
+ (differences are in <FONT COLOR="#008000">green</FONT>):</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>#ifndef INCLUDED_UCB_CACHEMAPOBJECT3_HXX
+#define INCLUDED_UCB_CACHEMAPOBJECT3_HXX
+
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _SAL_TYPES_H_
+#include "sal/types.h"
+#endif
+#ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_
+#include "salhelper/simplereferenceobject.hxx"
+#endif
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace rtl { class OUString; }
+namespace ucb { namespace cachemap { class Object3; } }
+
+namespace ucb { namespace cachemap {
+
+class ObjectContainer3: public salhelper::SimpleReferenceObject
+{
+public:
+ ObjectContainer3();
+
+ virtual ~ObjectContainer3() SAL_THROW(());
+
+ rtl::Reference< Object3 > get(rtl::OUString const & rKey);
+
+private:
+ typedef std::map< rtl::OUString, Object3 * > Map;
+
+ Map m_aMap;
+ osl::Mutex m_aMutex;
+
+ void releaseElement(Object3 * pElement) SAL_THROW(());
+
+ friend class Object3; // to access Map, releaseElement()
+};
+
+class Object3
+{
+public:
+ inline void acquire() SAL_THROW(())
+ { osl_incrementInterlockedCount(&m_nRefCount); }
+
+ <FONT COLOR="#008000">void release() SAL_THROW(());</FONT>
+
+private:
+ rtl::Reference< ObjectContainer3 > m_xContainer;
+ ObjectContainer3::Map::iterator m_aContainerIt;
+ oslInterlockedCount m_nRefCount;
+
+ inline Object3(rtl::Reference< ObjectContainer3 > const & rContainer);
+
+ inline ~Object3() SAL_THROW(());
+
+ Object3(Object3 &); // not implemented
+ void operator =(Object3); // not implemented
+
+ friend class ObjectContainer3;
+ // to access m_aContainerIt, m_nRefCount, Object3(), ~Object3()
+#if defined WNT
+ friend struct std::auto_ptr< Object3 >; // to access ~Object3()
+#else // WNT
+ friend class std::auto_ptr< Object3 >; // to access ~Object3()
+#endif // WNT
+};
+
+} }
+
+#endif // INCLUDED_UCB_CACHEMAPOBJECT3_HXX</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">Also, the implementation file
+ <A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemapobject3.cxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemapobject3.cxx</FONT></FONT></A>
+ has a strong resemblence to the implementation file from the first
+ solution (again, differences in <FONT COLOR="#008000">green</FONT>):</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+<PRE>#ifndef INCLUDED_UCB_CACHEMAPOBJECT3_HXX
+#include "cachemapobject3.hxx"
+#endif
+
+#ifndef _OSL_DIAGNOSE_H_
+#include "osl/diagnose.h"
+#endif
+#ifndef _OSL_INTERLOCK_H_
+#include "osl/interlck.h"
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include "osl/mutex.hxx"
+#endif
+#ifndef _RTL_REF_HXX_
+#include "rtl/ref.hxx"
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include "rtl/ustring.hxx"
+#endif
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+using ucb::cachemap::Object3;
+using ucb::cachemap::ObjectContainer3;
+
+inline
+Object3::Object3(rtl::Reference< ObjectContainer3 > const & rContainer):
+ m_xContainer(rContainer),
+ m_nRefCount(0)
+{
+ OSL_ASSERT(m_xContainer.is());
+}
+
+inline Object3::~Object3() SAL_THROW(())
+{}
+
+<FONT COLOR="#008000">void Object3::release() SAL_THROW(())</FONT>
+<FONT COLOR="#008000">{</FONT>
+<FONT COLOR="#008000"> if (osl_decrementInterlockedCount(&m_nRefCount) == 0)</FONT>
+<FONT COLOR="#008000"> {</FONT>
+<FONT COLOR="#008000"> m_xContainer->releaseElement(this);</FONT>
+<FONT COLOR="#008000"> delete this;</FONT>
+<FONT COLOR="#008000"> }</FONT>
+<FONT COLOR="#008000">}</FONT>
+
+void ObjectContainer3::releaseElement(Object3 * pElement) SAL_THROW(())
+{
+ OSL_ASSERT(pElement);
+ <FONT COLOR="#008000">osl::MutexGuard aGuard(m_aMutex);</FONT>
+<FONT COLOR="#008000"> if (pElement->m_aContainerIt != m_aMap.end())</FONT>
+<FONT COLOR="#008000"> m_aMap.erase(pElement->m_aContainerIt);</FONT>
+}
+
+ObjectContainer3::ObjectContainer3()
+{}
+
+ObjectContainer3::~ObjectContainer3() SAL_THROW(())
+{}
+
+rtl::Reference< Object3 > ObjectContainer3::get(rtl::OUString const & rKey)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ Map::iterator aIt(m_aMap.find(rKey));
+<FONT COLOR="#008000"> if (aIt == m_aMap.end())</FONT>
+<FONT COLOR="#008000"> {</FONT>
+<FONT COLOR="#008000"> std::auto_ptr< Object3 > xElement(new Object3(this));</FONT>
+<FONT COLOR="#008000"> aIt = m_aMap.insert(Map::value_type(rKey, xElement.get())).first;</FONT>
+<FONT COLOR="#008000"> aIt->second->m_aContainerIt = aIt;</FONT>
+<FONT COLOR="#008000"> xElement.release();</FONT>
+<FONT COLOR="#008000"> return aIt->second;</FONT>
+<FONT COLOR="#008000"> }</FONT>
+<FONT COLOR="#008000"> else if (osl_incrementInterlockedCount(&aIt->second->m_nRefCount) > 1)</FONT>
+<FONT COLOR="#008000"> {</FONT>
+<FONT COLOR="#008000"> rtl::Reference< Object3 > xElement(aIt->second);</FONT>
+<FONT COLOR="#008000"> osl_decrementInterlockedCount(&aIt->second->m_nRefCount);</FONT>
+<FONT COLOR="#008000"> return xElement;</FONT>
+<FONT COLOR="#008000"> }</FONT>
+<FONT COLOR="#008000"> else</FONT>
+<FONT COLOR="#008000"> {</FONT>
+<FONT COLOR="#008000"> osl_decrementInterlockedCount(&aIt->second->m_nRefCount);</FONT>
+<FONT COLOR="#008000"> aIt->second->m_aContainerIt = m_aMap.end();</FONT>
+<FONT COLOR="#008000"> aIt->second = new Object3(this);</FONT>
+<FONT COLOR="#008000"> aIt->second->m_aContainerIt = aIt;</FONT>
+<FONT COLOR="#008000"> return aIt->second;</FONT>
+<FONT COLOR="#008000"> }</FONT>
+}</PRE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">This implementation does not need to lock a mutex in every call to
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">Object3::release()</FONT></FONT>.
+ Only if the refcount drops to zero is the mutex of the
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer3</FONT></FONT>
+ locked and the object removed from the map. It is possible that an
+ <FONT SIZE=2><FONT FACE="Courier New, monospace">ObjectContainer3::get()</FONT></FONT>
+ gets in the way between dropping the refcount to zero and locking the
+ mutex. But the <FONT SIZE=2><FONT FACE="Courier New, monospace">get()</FONT></FONT>
+ method notices that (it goes through a cycle of incrementing and
+ decrementing the refcount itself, and if the refcount is not larger
+ than 1, the object is about to be deleted) and leaves alone the
+ to-be-deleted object and inserts into the map a fresh instance
+ instead.</P>
+ <P STYLE="margin-bottom: 0.1cm">Note that this implementation also does not have the drawback of
+ an ever-growing map, because each object is removed from the map as
+ soon as its refcount drops to zero.</P>
+ <P ALIGN=LEFT><BR></P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100% BGCOLOR="#666699">
+ <H3 ALIGN=LEFT STYLE="margin-top: 0cm; text-decoration: none"><A NAME="Measurements"></A>
+ <FONT COLOR="#ffffff"><FONT SIZE=4>Performance Measurements</FONT></FONT></H3>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <P STYLE="margin-bottom: 0.1cm">A simple test file
+ (<A HREF="http://www.openoffice.org/source/browse/ucb/ucb/workben/cachemap/cachemaptest.cxx"><FONT SIZE=2><FONT FACE="Courier New, monospace">cachemaptest.cxx</FONT></FONT></A>)
+ makes 200000 <FONT SIZE=2><FONT FACE="Courier New, monospace">get()</FONT></FONT>
+ requests, half of which find objects already present in the map. The
+ refcount of each requested object is incremented and decremented 50
+ times in a row. Only 100 different identifiers are used for the
+ objects, so that the second solution does not suffer from the problem
+ of an ever-growing map. The measurements for two of our production
+ platforms (Solaris Sparc with Forte compiler and Windows x86 with
+ Microsoft compiler) are as follows (all times in miliseconds; because
+ of different machines used, only comparisions within each column are
+ meaningful):</P>
+ <TABLE WIDTH=100% BORDER=1 CELLPADDING=4 CELLSPACING=3 STYLE="page-break-inside: avoid">
+ <COL WIDTH=85*>
+ <COL WIDTH=85*>
+ <COL WIDTH=85*>
+ <TR VALIGN=TOP>
+ <TD WIDTH=33%>
+ <P><BR>
+ </P>
+ </TD>
+ <TD WIDTH=33%>
+ <P>unxsols3.pro</P>
+ </TD>
+ <TD WIDTH=33%>
+ <P>wntmsci7.pro</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=33% VALIGN=TOP>
+ <P>Solution 1</P>
+ </TD>
+ <TD WIDTH=33% VALIGN=BOTTOM SDVAL="9137" SDNUM="1031;">
+ <P ALIGN=RIGHT>9137</P>
+ </TD>
+ <TD WIDTH=33% VALIGN=BOTTOM SDVAL="3846" SDNUM="1031;">
+ <P ALIGN=RIGHT>3846</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=33% VALIGN=TOP>
+ <P>Solution 2</P>
+ </TD>
+ <TD WIDTH=33% VALIGN=BOTTOM SDVAL="8634" SDNUM="1031;">
+ <P ALIGN=RIGHT>8634</P>
+ </TD>
+ <TD WIDTH=33% VALIGN=BOTTOM SDVAL="5598" SDNUM="1031;">
+ <P ALIGN=RIGHT>5598</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=33% VALIGN=TOP>
+ <P>Solution 3</P>
+ </TD>
+ <TD WIDTH=33% VALIGN=BOTTOM SDVAL="3166" SDNUM="1031;">
+ <P ALIGN=RIGHT>3166</P>
+ </TD>
+ <TD WIDTH=33% VALIGN=BOTTOM SDVAL="2704" SDNUM="1031;">
+ <P ALIGN=RIGHT>2704</P>
+ </TD>
+ </TR>
+ </TABLE>
+ <P ALIGN=LEFT><BR></P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100% BGCOLOR="#666699">
+ <P ALIGN=LEFT><FONT COLOR="#ffffff">Author: <A HREF="mailto:bergmann@sun.com">Stephan
+ Bergmann</A> ($Date: 2001/06/14 14:49:37 $)<BR><I>Copyright 2001
+ OpenOffice.org Foundation. All Rights Reserved.</I></FONT>
+ </P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=100%>
+ <HR SIZE=1 NOSHADE>
+ </TD>
+ </TR>
+</TABLE>
+<HR SIZE=3 NOSHADE>
+</BODY>
+</HTML>
Propchange: incubator/ooo/ooo-site/trunk/content/ucb/docs/cachemap.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html
URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html?rev=1206884&view=auto
==============================================================================
--- incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html (added)
+++ incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html Sun Nov 27 22:36:56 2011
@@ -0,0 +1,516 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="CONTENT-TYPE" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.78 [en] (Windows NT 5.0; U) [Netscape]">
+ <meta name="AUTHOR" content="Kai Sommerfeld">
+ <meta name="CREATED" content="20010528;10585075">
+ <meta name="CHANGEDBY" content="Kai Sommerfeld">
+ <meta name="CHANGED" content="20010608;9152226">
+</head>
+<body>
+
+<table BORDER=0 CELLSPACING=0 CELLPADDING=4 WIDTH="100%" STYLE="page-break-before: always" >
+<tr>
+<td BGCOLOR="#666699">
+<center>
+<h1 STYLE="margin-top: 0cm; text-decoration: none">
+<a href="http://www.openoffice.org/"><img SRC="../images/open_office_org_logo.gif" NAME="Graphic1" ALT="OpenOffice.org" NOSAVE BORDER=0 height=53 width=126 align=RIGHT></a><font color="#FFFFFF"><font size=+3>
+UCB Commands - Error Handling Concept & Specification</font></font></h1></center>
+</td>
+</tr>
+</table>
+
+<hr SIZE=3 NOSHADE>
+<table BORDER=0 CELLSPACING=0 CELLPADDING=4 WIDTH="100%" STYLE="page-break-before: always" >
+<tr>
+<td WIDTH="100%" BGCOLOR="#666699">
+<h3 STYLE="margin-top: 0cm; text-decoration: none">
+<font color="#FFFFFF"><font size=+1>General Error Handling Concept</font></font></h3>
+</td>
+</tr>
+
+<tr>
+<td WIDTH="100%">Every UCB Content supports a set of commands. A UCB client
+calls
+<b>css::ucb::XCommandProcessor::execute(...)</b> if it wants the
+content to execute a command. Errors occurring while executing a command
+are managed using exceptions.
+<p>Any exceptions can be used by a UCP implementation to interact with
+a UCB client. For example, if a file should be written to disk (using UCB's
+<i>insert</i>
+command) and another file with the same name already exists, an exception
+could be used to query the user whether he wants to overwrite the existing
+file. If the user confirms, the file will be overwritten, if he rejects,
+the insert command will be aborted.
+<p>Exceptions generally should be handed over to an
+<b>css::task::XInteractionHandler</b>
+implementation, which generally was obtained from a command's environment
+(<b>css::ucb::XCommandEnvironment</b>. If no Interaction handler is available
+or if the Interaction Handler did not handle the request, the exception
+must be thrown directly. This will always aborts the command. Using an
+Interaction Handler has the advantage, that additional data can be supplied
+to the command implementation without the need to abort and to retry the
+command (after supplying the missing data). The data supplied to the requesting
+code either may lead in continuing or aborting the command.
+<p>A <b>css::task::XInteractionHandler</b> handles <b>css::task::XInteractionRequest</b>s.
+An Interaction Request contains an exception (the request) and a number
+of <b>css::task::XInteractionContinuation</b>s, which define the responses
+that can be used to "answer" the request. There are some standard continuations
+defined, which are namely
+<b>css::task::XInteractionAbort</b>, <b>css::task::XInteractionRetry</b>,
+<b>css::task::XInteractionApprove</b>
+and
+<b>css::task::XInteractionDisapprove</b>. For example, for a GUI Interaction
+Handler these continuations could be assigned to buttons in a message box
+(Approve equals "Yes" button, Disapprove equals "No" button, ...). The
+Interaction Handler code does some work dependent on the kind of request
+and the possible continuations (like displaying a login dialog and supplying
+the data entered to the authentication request),
+<i>selects</i> one of
+the continuations provided and returns. The code that called the Interaction
+Handler now can act according to the kind of continuation that was previously
+selected. Not every Interaction Handler implementation must be able to
+handle all requests. If an Interaction Handler cannot handle a request,
+no continuation will be selected after the call to XInteractionHandler::handle(
+... ). In this case the code that called the Interaction Handler must act
+as if no handler were available and throw the exception that was previously
+passed to the Interaction Handler.
+<p>For exceptions located in the module <b>com::sun::star::ucb</b>, the
+member <i>Context</i> (which is introduced by the base class of all UNO
+exceptions css::uno::Exception) should be filled with the command processor
+(<b>css::ucb::XCommandProcessor</b> implementation) that executes the command.
+<p>The following pseudo code illustrates how to proceed with an error:
+<br>
+<table BORDER CELLSPACING=0 CELLPADDING=4 WIDTH="100%" BORDERCOLOR="#000000" >
+<tr>
+<td VALIGN=TOP>
+<pre><font face="Courier, monospace"><font size=-1>// Create the exception to propagate...
+xxxxException aEx( ... );
+
+xxxxContinuation aCont;</font></font></pre>
+
+<pre>// Obtain Interaction Handler
+<font face="Courier, monospace"><font size=-1>uno::Reference< task::XInteractionHandler > xIH = ...
+
+bool bSelection = false;
+if ( xIH.is() )
+{
+ // IH available. Create Interaction Request.
+ xxxxRequest aReq = ...( aEx, ... );
+
+ // Pass over the request to the IH.
+ xIH.handle( aReq );
+
+ // Get selected continuation
+ aCont = aReq.getSelection();
+
+ // Was IH able to handle the request?
+ if ( aCont.is() )
+ bSelection = true;
+}
+
+// Act according to bSelection and aCont
+bool bSuccess = ...;
+
+if ( !bSuccess )
+{
+ if ( !bSelection )
+ {
+ // No IH or IH did not handle exception.
+ throw aEx;
+ }</font></font></pre>
+
+<pre> // IH handled the selection.
+<font face="Courier, monospace"><font size=-1> throw ucb::CommandFailedException( aEx );
+}
+
+// Continue...</font></font></pre>
+</td>
+</tr>
+</table>
+</td>
+</tr>
+
+<tr>
+<td WIDTH="100%" BGCOLOR="#666699">
+<h3 STYLE="margin-top: 0cm; text-decoration: none">
+<font color="#FFFFFF"><font size=+1>Exception Specifications for the Well-Known
+UCB Commands</font></font></h3>
+</td>
+</tr>
+
+<tr>
+<td WIDTH="100%">There is a number of predefined exceptions for the well-known
+UCB Commands. Every new command introduced by a UCB Content implementation
+can also introduce new exceptions. If these exceptions are interactive,
+there is the problem, that any existing Interaction Handlers most possibly
+won't be able to handle them. Thus reusing existing interactive exceptions
+should be the way of choice whenever possible.
+<p>The implementation of a command should use the predefined exception
+for the appropriate error condition whenever possible. But It can use any
+other exceptions, for example, if there is no matching predefined exception
+for a concrete error condition.
+<br>
+<h3>
+All commands</h3>
+The following exceptions can be thrown by all UCB Commands:
+<br>
+<table BORDER CELLSPACING=3 CELLPADDING=4 WIDTH="100%" >
+<tr VALIGN=TOP>
+<th>Exception</th>
+
+<th>Description</th>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::UnsupportedCommandException</td>
+
+<td>Thrown if the requested command is not supported by a content.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::lang::IllegalArgumentException</td>
+
+<td>Thrown if the data type of the given command's argument does not match
+the command's definition.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::InteractiveAugmentedIOException</td>
+
+<td>Used to indicate IO errors (exception contains an css::ucb::IOErrorCode)</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb:InteractiveNetworkResolveNameException</td>
+
+<td></td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb:InteractiveNetworkConnectException</td>
+
+<td></td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb:InteractiveNetworkReadException</td>
+
+<td></td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb:InteractiveNetworkWriteException</td>
+
+<td></td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb:InteractiveNetworkGeneralException</td>
+
+<td></td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb:InteractiveNetworkOffLineException</td>
+
+<td></td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::AuthenticationRequest</td>
+
+<td>Used to collect missing authentication information. An implementation
+of css::ucb::XInteractionSupplyAuthentication (that will be filled by the
+Interaction Handler with the missing data) should be supplied with the
+continuations.</td>
+</tr>
+</table>
+
+<p>Exceptions, that are never passed to an Interaction Handler:
+<br>
+<table BORDER CELLSPACING=3 CELLPADDING=4 WIDTH="100%" >
+<tr VALIGN=TOP>
+<th>Exception</th>
+
+<th>Description</th>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::CommandFailedException</td>
+
+<td>Thrown if the execution of the command failed (but only after communication
+with an Interaction Handler). This exception contains the "original" exception
+that was passed to the Interaction Handler.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::CommandAbortedException</td>
+
+<td>Thrown if the execution of the command was ended by calling css::ucb::XCommandProcessor::abort().</td>
+</tr>
+
+<tr>
+<td>css::ucb::DuplicateCommandIdentifierException</td>
+
+<td>Thrown if two threads passed the same (non-zero) command identifier
+to css::ucb::XCommandProcessor::execute().</td>
+</tr>
+</table>
+
+<h3>
+getCommandInfo</h3>
+No special exceptions defined.
+<h3>
+getPropertySetInfo</h3>
+No special exceptions defined.
+<h3>
+getPropertyValues</h3>
+No special exceptions defined. Note that most error handling (except command
+name and parameter checking ) is done using the css::sdbc::XRow implementation
+returned by this command.
+<h3>
+setPropertyValues</h3>
+<b>Note that setPropertyValues does not throw an exception in the case
+that one or more of the requested property values cannot be set!</b> The
+implementation should set as much property values as possible. This command
+returns a <b>sequence< any ></b> which has exactly the same number of
+elements like the number of properties to set. Every sequence element contains
+the status for a property. The first sequence elements corresponds to the
+first element in the sequence of
+<b>css::beans::PropertyValue</b>s passed
+as command argument and so on. The exceptions will never be passed to an
+Interaction Handler by the implementation of the setPropertyValues command.
+<p>An <b>any</b> containing:
+<ul>
+<li>
+<b>No value</b> indicates, that the property value was set successfully.</li>
+
+<li>
+<b>css::beans::UnknownPropertyException</b> indicates, that the property
+is not known to the content implementation.</li>
+
+<li>
+<b>css::beans::IllegalTypeException</b> indicates, that the data type of
+the property value is not acceptable.</li>
+
+<li>
+<b>css::lang::IllegalAccessException</b> indicates, that the property is
+constant (css::beans::PropertyAttribute::READONLY is set).</li>
+
+<li>
+<b>css::lang::IllegalArgumentException</b> indicates, that the property
+value is not acceptable. For instance, setting an empty title may be illegal.</li>
+
+<li>
+<b>Any other execption derived from css::uno::Exception</b> indicates,
+that the value was not set successfully. For example, this can be a css::ucb::InteractiveAugmentedIOException
+transporting the error code css::ucb::IOErrorCode::ACCESS_DENIED.</li>
+</ul>
+If the value to set is equal to the current value, no exception must be
+added to the returned sequence
+<h3>
+open</h3>
+
+<table BORDER CELLSPACING=3 CELLPADDING=4 WIDTH="100%" >
+<tr VALIGN=TOP>
+<th>Exception</th>
+
+<th>Description</th>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::UnsupportedOpenModeException</td>
+
+<td>Used to indicate that the requested css::ucb::OpenMode is not supported.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::UnsupportedDataSinkException</td>
+
+<td>Used to indicate that the type of data sink supplied is not supported.</td>
+</tr>
+</table>
+
+<h3>
+delete</h3>
+No special exceptions defined.
+<h3>
+insert</h3>
+<table BORDER CELLSPACING=3 CELLPADDING=4 WIDTH="100%" >
+<tr VALIGN=TOP>
+<th>Exception</th>
+
+<th>Description</th>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::MissingPropertiesException</td>
+
+<td>Used if one or more properties were not set that are needed to make
+the content persistent (like the name for a newly created file). The exception
+transports a list of property names.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::MissingInputStreamException</td>
+
+<td>Used if no css::io::XInputStream was given with the command argument,
+but is required.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::UnsupportedNameClashException</td>
+
+<td>Used if the parameter <i>ReplaceExisting</i> of the command's argument
+was set to <i>false</i> and the implementation is unable to determine whether
+there are existing data. The member <i>NameClash</i> of the exception must
+be set to <i>NameClash::ERROR</i>.
+<br>Must also be thrown in case the requested nameclash is just not yet
+implemented (a missing feature, so to speak).</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::NameClashException</td>
+
+<td>Used if the parameter <i>ReplaceExisting</i> of the command's argument
+was set to <i>false</i> and there exists a resource with a clashing name
+in the target folder of the operation.</td>
+</tr>
+</table>
+
+<h3>
+transfer</h3>
+<table BORDER CELLSPACING=3 CELLPADDING=4 WIDTH="100%" >
+<tr VALIGN=TOP>
+<th>Exception</th>
+
+<th>Description</th>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::InteractiveBadTransferURLException</td>
+
+<td>Used if the Source URL given with the command's argument is not supported
+by the command's implementation. For example, an FTP-UCP needs not be able
+to handle other URLs then FTP-URLs.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::UnsupportedNameClashException</td>
+
+<td>Used if the nameclash directive specified in parameter <i>NameClash</i>
+of command's argument is not supported. For example, if the <i>NameClash</i>
+was set to <i>NameClash::ERROR,</i> to <i>NameClash::RENAME</i> or to <i>NameClash::ASK,</i>
+the implementation must be able determine whether there are existing data.
+<br>This exception must also used if <i>NameClash::RENAME</i> was specified
+and the implementation is unable to create a valid new name after a suitable
+number of tries.
+<br>It must also be thrown in case the requested nameclash is just not yet
+implemented (a missing feature, so to speak).</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::NameClashException</td>
+
+<td>Used if the parameter <i>NameClash</i> of the command's argument was
+set to <i>NameClash::ERROR</i> and there exists a resource with a clashing
+name in the target folder of the operation.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::NameClashResolveRequest</td>
+
+<td>If the parameter <i>NameClash</i> of the command's argument was set
+to <i>NameClashh::ASK</i> this interaction request can be used to obtain
+a new name. Implementations of css::ucb::XInteractionSupplyName and css::ucb::XInteractionReplaceExistingData
+(that will be filled by the Interaction Handler with the missing data)
+should be supplied with the continuations.</td>
+</tr>
+</table>
+
+<h3>
+globalTransfer</h3>
+<table BORDER CELLSPACING=3 CELLPADDING=4 WIDTH="100%" >
+<tr VALIGN=TOP>
+<th>Exception</th>
+
+<th>Description</th>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::UnsupportedNameClashException</td>
+
+<td>Used if the nameclash directive specified in parameter <i>NameClash</i>
+of command's argument is not supported. For example, if the <i>NameClash</i>
+was set to <i>NameClash::ERROR,</i> to <i>NameClash::RENAME</i> or to <i>NameClash::ASK,</i>
+the implementation must be able determine whether there are existing data.
+<br>This exception must also used if <i>NameClash::RENAME</i> was specified
+and the implementation is unable to create a valid new name after a suitable
+number of tries.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::NameClashException</td>
+
+<td>Used if the parameter <i>NameClash</i> of the command's argument was
+set to <i>NameClash::ERROR</i> and there exists a resource with a clashing
+name in the target folder of the operation.</td>
+</tr>
+
+<tr VALIGN=TOP>
+<td>css::ucb::NameClashResolveRequest</td>
+
+<td>If the parameter <i>NameClash</i> of the command's argument was set
+to <i>NameClashh::ASK</i> this interaction request can be used to obtain
+a new name. Implementations of css::ucb::XInteractionSupplyName and css::ucb::XInteractionReplaceExistingData
+(that will be filled by the Interaction Handler with the missing data)
+should be supplied with the continuations.</td>
+</tr>
+</table>
+
+<h3>
+search</h3>
+Not yet specified. Will be done later. (No implementations yet.)
+<h3>
+update</h3>
+Not yet specified. Will be done later. (No implementations yet.)
+<h3>
+synchronize</h3>
+Not yet specified. Will be done later. (No implementations yet.)
+<h3>
+close</h3>
+Not yet specified. Will be done later. (No implementations yet.)
+<h3>
+undelete</h3>
+Not yet specified. Will be done later. (No implementations yet.)</td>
+</tr>
+
+<tr>
+<td WIDTH="100%">
+<hr SIZE=1 NOSHADE></td>
+</tr>
+
+<tr>
+<td WIDTH="100%">
+<hr SIZE=1 NOSHADE></td>
+</tr>
+
+<tr>
+<td WIDTH="100%" BGCOLOR="#666699"><font color="#FFFFFF">Author: <a href="mailto:kai.sommerfeld@germany.sun.com">Kai
+Sommerfeld</a> ($Date: 2007/05/26 10:33:56 $)</font>
+<br><i><font color="#FFFFFF">Copyright 2001 OpenOffice.org Foundation.
+All Rights Reserved.</font></i></td>
+</tr>
+
+<tr>
+<td WIDTH="100%">
+<hr SIZE=1 NOSHADE></td>
+</tr>
+</table>
+
+<hr SIZE=3 NOSHADE>
+</body>
+</html>
Propchange: incubator/ooo/ooo-site/trunk/content/ucb/docs/errorhandling.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html
URL: http://svn.apache.org/viewvc/incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html?rev=1206884&view=auto
==============================================================================
--- incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html (added)
+++ incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html Sun Nov 27 22:36:56 2011
@@ -0,0 +1,192 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+<HEAD>
+ <TITLE>Be Careful with file URLs</TITLE>
+
+<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
+</head>
+<BODY>
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="4">
+ <TR>
+ <TD BGCOLOR="#666699">
+ <H1 ALIGN="CENTER" STYLE="margin-top: 0in; text-decoration: none"><A HREF="http://www.openoffice.org"><IMG SRC="../images/open_office_org_logo.gif" ALT="OpenOffice.org" ALIGN="RIGHT" BORDER="0"></A><FONT COLOR="White">Be Careful with file URLs</FONT></H1>
+ </TD>
+ </TR>
+</TABLE>
+<HR NOSHADE SIZE="3">
+
+<H2>Different Ways to Name Files</H2>
+
+<P>There are (at least) five ways to name files:</P>
+<OL>
+ <LI>
+ <P>The platform-specific notation, called <B>pathnames</B> here
+ (e.g., <CODE>/abc/def/ghi.txt</CODE> on Unix,
+ <CODE>a:\bcd\efg\hij.txt</CODE> on DOS and Windows, and
+ <CODE>abc:def:ghi.txt</CODE> on Macintosh).</P>
+ </LI>
+ <LI>
+ <P>A UNC-like notation, called <B>UNC names</B> here (e.g.,
+ <CODE>//./abc/def/ghi.txt</CODE> or
+ <CODE>//./a:/bcd/efg/hij.txt</CODE>). The osl layer used to make
+ heavy use of these as a platform-independent notation, but since osl
+ has shifted to file URLs as the platform-independent notation (see
+ below), UNC names have been deprecated and became pretty much useless
+ (and are only mentioned here for completeness).</P>
+ </LI>
+ <LI>
+ <P>The file URLs used by the osl layer as a platform-independent
+ notation, called <B>osl URLs</B> here (e.g.,
+ <CODE>file:///abc/def/ghi.txt</CODE> or
+ <CODE>file:///a:/bcd/efg/hij.txt</CODE>). Read on to learn why it is
+ important to explicitly label these file URLs as <EM>osl</EM>
+ URLs.</P>
+ </LI>
+ <LI>
+ <P>The file URLs used by the File Content Provider (FCP) within the
+ Universal Content Broker (UCB), called <B>FCP URLs</B> (e.g.,
+ <CODE>file:///home/usr123/work/abc.txt</CODE> or
+ <CODE>file:///user/work/abc.txt</CODE>). Normally, osl URLs and FCP
+ URLs are the same (after all, the FCP uses osl to access the files).
+ But the FCP has a feature called <EM>mount points</EM> that allows it
+ to restrict access to only certain files (those that lie below a given
+ set of mount points in the file system hierarchy), and to give names
+ to these files that hide their real locations.<P>
+
+ <P>For example, if you have a mount point named <code>user</code> at
+ the osl URL <code>file:///home/usr123</code>, the osl URL
+ <code>file:///home/usr123/work/abc.txt</code> corresponds to the FCP
+ URL <code>file:///user/work/abc.txt</code>. If you only have that
+ single mount point, the osl URL
+ <code>file:///home/usr567/work/def.txt</code> has no corresponding FCP
+ URL (and cannot be accessed via the FCP).</P>
+ </LI>
+ <LI>
+ <P>The URLs used by the UCB, called <B>UCB URLs</B> (e.g.,
+ <CODE>file:///a:/bcd/efg/hij.txt</CODE> or
+ <CODE>vnd.sun.star.wfs:///user/work/abc.txt</CODE>). Normally, FCP
+ URLs and UCB URLs are the same, because the UCB hands file URLs
+ directly to the FCP. But there is a special content provider, the
+ Remote Access Content Provider (RAP), that allows to rewrite URLs
+ before passing them on to other content providers. This is used, for
+ example, in the Sun ONE Webtop (S1W), where there are typically two
+ file systems: a client file system accessed via normal (FCP) file URLs
+ (i.e., there is no rewriting RAP between the UCB and the client FCP),
+ and a server file system accessed via (FCP) URLs where the
+ <CODE>file</CODE> scheme has been replaced with
+ <CODE>vnd.sun.star.wfs</CODE> (i.e., there is a rewriting RAP between
+ the UCB and the server FCP).</P>
+ </LI>
+</OL>
+
+<P>The last two notations (FCP URLs and UCB URLs) are relatively unknown,
+because in a plain OpenOffice installation neither mount points nor the RAP
+are used, so that osl URLs, FCP URLs and UCB URLs are all identical. But when
+you want to write correct code that also works in unusal deployments (or in
+the S1W, which should be regarded not too unusal), you have to be well aware
+of these different notations all labeled as "URLs."</P>
+
+<H2>Where Different Notations are Used</H2>
+
+<P>As mentioned before, use of UNC names is deprecated. Also, since most code
+accesses the FCP not directly, but via the UCB, FCP URLs are only of interest
+to hard core UCB users (who should know what they are doing, anyway). So, in
+the following we can concentrate on three different notations: pathnames, osl
+URLs, and UCB URLs.</P>
+
+<H3>Where Pathnames are Used</H3>
+
+<P>Pathnames are used in only a few places, because the default notation used
+by osl (the lowest level of concern to us) already are osl URLs (which are a
+level above pathnames). It can be argued that interfaces that use pathnames
+should use osl URLs instead, and that pathnames are only of interest when
+communicating with the external world (other processes, or the human
+user).</P>
+
+<P>One place where pathnames are used is class <code>utl::TempFile</code>.</P>
+
+<H3>Where osl URLs are Used</H3>
+
+<P>The osl file system functions (in <code>osl/file.h</code> and
+<code>osl/file.hxx</code>) now generally use osl URLs in their interfaces.</P>
+
+<P>There should be few places above osl where osl URLs instead of UCB URLs are
+used (because generally all file access should be done through the UCB, and
+not directly via osl). One notable exception is the handling of temporary
+files (see above).</P>
+
+<H3>Where UCB URLs are Used</H3>
+
+<P>Generally, all interfaces that are designed to communicate resource names
+within the OpenOffice framework should use UCB URLs, and all implemenations
+that access resources by these names should do so via the UCB. Another
+advantage of this is that without any extra effort not only file resources can
+be accessed, but also other resources like HTTP and FTP (by using appropriate
+URLs, but these URLs can be opaque to the code, only interpreted by the
+UCB).</P>
+
+<H2>Converting between Different Notations</H2>
+
+<P>Sometimes it may be necessary to convert between different notations, and
+the routines to do so are well available:</P>
+<UL>
+ <LI>
+ <P>The methods <code>osl::FileBase::getFileURLFromSystemPath()</code>
+ and <code>osl::FileBase::getSystemPathFromFileURL()</code> (and their
+ plain C counterparts in <code>osl/file.h</code>) convert between
+ pathnames (called "system paths" here) and osl URLs.</P>
+ </LI>
+ <LI>
+ <P>The methods
+ <code>utl::LocalFileHelper::ConvertSystemPathToURL()</code> and
+ <code>utl::LocalFileHelper::ConvertURLToSystemPath()</code> convert
+ between pathnames (again called "system paths" here) and UCB URLs.</P>
+
+ <P>Because there can be scenarios where you have multiple FCPs on
+ different file systems, it can be ambigious how to convert from a
+ pathname (that does not contain any information identifying a specific
+ file system) to a UCB URL. Therefore,
+ <code>ConvertSystemPathToURL()</code> requires an additional parameter
+ <code>BaseURL</code> that identifies the FCP to be used.</P>
+ </LI>
+ <LI>
+ <P>There are convenience methods
+ <code>utl::LocalFileHelper::ConvertPhysicalNameToURL()</code> and
+ <code>utl::LocalFileHelper::ConvertURLToPhysicalName()</code> that
+ choose the <EM>local</EM> FCP as <code>BaseURL</code> and then forward
+ to the above <code>LocalFileHelper</code> methods.</P>
+
+ <P>For this to work, the UCB maintains a notion of <EM>locality</EM>
+ of content providers. This is an heuristic algorithm based on how the
+ UCB accesses individual content providers (within the same process,
+ via a pipe on the same machine, via a socket over a network). The net
+ effect is that the UCB should always choose as most local the FCP
+ running on the same machine as the UCB, and using these
+ <code>LocalFileHelper</code> methods will then always convert between
+ UCB URLs and pathnames that are valid on this machine.</P>
+
+ <P><code>ConvertURLToPhysicalName()</code> also makes sure to do the
+ conversion only if the given UCB URL corresponds to a local pathname
+ (and not to a pathname on a non-local file system).</P>
+ </LI>
+</UL>
+
+<P>There is no direct way to convert between osl URLs and UCB URLs. To
+convert from an osl URL to a UCB URL, use
+<code>osl::FileBase::getSystemPathFromFileURL()</code> followed by
+<code>utl::LocalFileHelper::ConvertPhysicalNameToURL()</code>. To convert
+from a UCB URL to an osl URL, use
+<code>utl::LocalFileHelper::ConvertURLToPhysicalName()</code> followed by
+<code>osl::FileBase::getFileURLFromSystemPath</code>. But be aware that this
+only works if the osl URL and the UCB URL shall denote files within the same
+file system.</P>
+
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="4">
+ <TR>
+ <TD BGCOLOR="#666699">
+ <P><FONT COLOR="White">Author: <A HREF="mailto:stephan.bergmann@sun.com"><FONT COLOR="White">Stephan Bergmann</FONT></A> (Last modification $Date: 2003/12/06 22:37:31 $). Copyright 2001 <A HREF="http://www.openoffice.org"><FONT COLOR="White">OpenOffice.org</FONT></A> Foundation. All Rights Reserved.</FONT></P>
+ </TD>
+ </TR>
+</TABLE>
+</BODY>
+</HTML>
Propchange: incubator/ooo/ooo-site/trunk/content/ucb/docs/fileurl.html
------------------------------------------------------------------------------
svn:eol-style = native