2022-04-24

281: Homeomorphic Topological Manifolds Can Have Equivalent Atlases

<The previous article in this series | The table of contents of this series | The next article in this series>

A description/proof of that homeomorphic topological manifolds can have equivalent atlases

Topics


About: topological manifold
About: \(C^\infty\) manifold

The table of contents of this article


Starting Context



Target Context


  • The reader will have a description and a proof of the proposition that any homeomorphic topological manifolds can have equivalent atlases or no atlas.

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Description


For any topological manifolds, \(M_1\) and \(M_2\), that are homeomorphic to each other by \(f: M_1 \rightarrow M_2\), if \(M_1\) can have an atlas, \(M_2\) can have the equivalent atlas; if \(M_1\) can have no atlas, \(M_2\) can have no atlas.

"equivalent" there means that for any chart, \((U, \phi)\) on \(M_1\), the corresponding chart on \(M_2\) is \((f (U), \phi (f^{-1}))\).


2: Proof


\((f (U), \phi (f^{-1}))\) is a chart, because \(\phi (f^{-1})\) is a homeomorphism from f (U), open on \(M_2\) (because f is a homeomorphism), to \(\phi (U)\), open on \(\mathbb{R}^n\) (because \(\phi\) is the char map), as the compound of homeomorphisms. The set of the charts on \(M_2\) forms an \(C^\infty\) atlas, because it covers \(M_2\) (any point on \(M_2\) is f (p), so it is in f (U) where \(p \in U\)); for any area shared by \(f (U_1)\) and \(f (U_2)\), the charts transition map, \(\phi_1 (f^{-1} (f (U_1))) \rightarrow \phi_2 (f^{-1} (f (U_2)))\), is \(\phi_1 (U_1) \rightarrow \phi_2 (U_2)\), which is nothing but the charts transition map on \(M_1\), \(C^\infty\).

If \(M_1\) can have no atlas, \(M_2\) can have no atlas, because if \(M_2\) had an atlas, there would be the equivalent atlas on \(M_1\), a contradiction.


3: Note


Some people will deem this proposition obvious: "The 2 topological manifolds are the same, because they are homeomorphic!".

Well, one of my pet peeves for some prevalent discourses on topological space or manifold is that they breezily say that "2 entities are the same" just because they are equivalent. 'Being equivalent' means 'sharing a set of properties', not 'being the same'.

Even if the Earth surface and the Mars surface are homeomorphic, they are not the same: a point you are standing at is not any point on the Mars surface, even if the point homeomorphicly corresponds to a point on the Mars surface.

I have bothered to describe and prove the proposition, because I am offended by such breeziness, although some quick-witted people may deem the proposition obvious anyway. .

The breezy people will say "The topological manifolds share the same atlas.", but I say that the 2 atlas are just equivalent, not the same.

An atlas for the Earth surface is not any atlas for the Mars surface, even if a Mars surface atlas can be derived from the Earth surface atlas via the homeomorphism.


References


<The previous article in this series | The table of contents of this series | The next article in this series>

280: Homeomorphism

<The previous article in this series | The table of contents of this series | The next article in this series>

A definition of homeomorphism

Topics


About: topological space
About: map

The table of contents of this article


Starting Context



Target Context


  • The reader will have a definition of homeomorphism.

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Definition


For any topological spaces, \(T_1\) and \(T_2\), the pair of any bijective map and its inverse, \(f: T_1 \rightarrow T_2\) and \(f^{-1}: T_2 \rightarrow T_1\), that are continuous


References


<The previous article in this series | The table of contents of this series | The next article in this series>

279: Map

<The previous article in this series | The table of contents of this series | The next article in this series>

A definition of map

Topics


About: set

The table of contents of this article


Starting Context



Target Context


  • The reader will have a definition of map.

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Definition


For any sets, \(S_1\) and \(S_2\), any association that makes each element of \(S_1\) (\(S_1\) is called 'the domain') correspond to an element of \(S_2\) (\(S_2\) is called 'the range')


2: Note


Some elements of the range may not be corresponded to by any element of the domain. Any element of the domain is not allowed to correspond to multiple elements of the range, although some multiple elements of the domain may correspond to the same element of the range.


References


<The previous article in this series | The table of contents of this series | The next article in this series>

278: Equivalence Between Derivation at Point of C^1 Functions and Directional Derivative

<The previous article in this series | The table of contents of this series | The next article in this series>

A description/proof of equivalence between derivation at point of \(C^1\) functions and directional derivative

Topics


About: \(C^\infty\) manifold

The table of contents of this article


Starting Context



Target Context


  • The reader will have a description and a proof of the equivalence between any derivation at point of \(C^1\) functions and the corresponding directional derivative.

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Description


For any \(C^\infty\) manifold, M, any point, \(p \in M\), the set, \(\mathfrak{D}^1_p (M)\), of derivations at p of \(C^1\) functions, and the set, \(T_pM\), of directional derivatives, the map, \(\phi: T_pM \rightarrow \mathfrak{D}^1_p (M)\), \(\frac{d f ({v^i t})}{d t} \mapsto v^i \frac{\partial f}{\partial x_i}\) on any chart where \({v^i}\) is any combination of real numbers, is an isomorphism, which does not really depend on the choice of the chart, with the same result on any \(C^1\) function.


2: Proof


Any directional derivative can be represented by \(c (t) = {v^1 t, v^2 t, . . ., v^n t}\) with the unique \({v^1, v^2, . . ., v^n}\), because only the tangent of the curve at p matters. \(v^i \frac{\partial f}{\partial x_i}\) is a derivation at p, because \(v^i \frac{\partial f g}{\partial x_i} = v^i \frac{\partial f}{\partial x^i} g + f v^i \frac{\partial g}{\partial x^i}\), satisfying the Leibniz rule. The map is an injection, because for 2 distinct \({v_1^1, v_1^2, . . ., v_1^n}\) and \({v_2^1, v_2^2, . . ., v_2^n}\) with f as \(x^i\), the results are \(v_1^i\) and \(v_2^i\), which differ for an i. The map is a surjection, because by Tailor's theorem with reminder, any \(C^1\) function, f, satisfies \(f (x) = f (p) + (x^i - p^i) f_{r_i} (x)\) where \(f_{r_i} (p) = \frac{\partial f}{\partial x^i} (p)\). Applying any derivation at p on the both sides, \(D_v (f (x))|_p = (D_v ( (x^i - p^i)))|_p f_{r_i} (p) + (p^i - p^i) (D_v (f_{r_i} (x))|_p = (D_v (x^i - p^i))|_p f_{r_i} (p) + 0 = (D_v (x^i))|_p \frac{\partial f}{\partial x^i}|_p\). So, any derivation at p can be expressed as with \((v^1, v^2, . . ., v^n) = (D_v (x^1)|_p, D_v (x^2)|_p, . . ., D_v (x^n)|_p)\).

The result of any derivation is the same with that of the corresponding directional derivative, because \(\frac{d f ({v^i t})}{d t} = \frac{\partial f (x)}{\partial x^i} v_i\) by the chain rule.

The isomorphism does not depend on the choice of chart, because directional derivative does not depend on the choice and derivation equals the choice-independent directional derivative.


3: Note


Derivation at point of \(C^\infty\) functions is equivalent with directional derivative with the domain restricted to \(C^\infty\) functions, because as any \(C^\infty\) function is a \(C^1\) function, the map, \(\frac{d f ({v^i t})}{d t} \mapsto v^i \frac{\partial f}{\partial x_i}\), works for any \(C^\infty\) function, the injectivity and the surjectivity are intact (because the materials used in the proof for \(C^1\) functions can be used also for this case: \(x^i\) is \(C^\infty\) as well as \(C^1\) and the Tailor theorem works for \(C^\infty\) functions, which are \(C^1\) functions), and the both sides yields the same result with the domains just restricted. We have to say "directional derivative with the domain restricted to \(C^\infty\) functions", because \(C^\infty_p (M) \rightarrow \mathbb{R}\) cannot be said to be exactly equivalent with \(C^1_p (M) \rightarrow \mathbb{R}\).


References


<The previous article in this series | The table of contents of this series | The next article in this series>

277: Directional Derivative

<The previous article in this series | The table of contents of this series | The next article in this series>

A definition of directional derivative

Topics


About: \(C^\infty\) manifold
About: function

The table of contents of this article


Starting Context



Target Context


  • The reader will have a definition of directional derivative.

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Definition


For any \(C^\infty\) manifold, M, and any point, \(p \in M\), any map, \(D_v: C^1_p \rightarrow \mathbb{R}\) such that there is a \(C^\infty\) curve, c (t), \(p = c (t_0)\), such that \(D_v (f) = lim_{t \rightarrow t_0} \frac{f (c (t)) - f (p)}{t - t_0}\)


2: Note


The same directional derivative can be represented by many curves and can be especially by the straight line on any chart, because only the tangent of the curve at the point matters.


References


<The previous article in this series | The table of contents of this series | The next article in this series>

2022-04-17

59: Tangent Vector

<The previous article in this series | The table of contents of this series | The next article in this series>

A definition of tangent vector

Topics


About: \(C^\infty\) manifold with boundary

The table of contents of this article


Starting Context



Target Context


  • The reader will have a definition of tangent vector.

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Definition


For any \(C^\infty\) manifold with (possibly empty) boundary, \(M\), and any point, \(p \in M\), any derivation at \(p\) of \(C^\infty\) functions


2: Note


\(C^\infty\) manifold with boundary, not just topological manifold with boundary, is required, because \(C^\infty\)-ness of function requires \(C^\infty\) manifold with boundary.


References


<The previous article in this series | The table of contents of this series | The next article in this series>

58: Derivation at Point of \(C^k\) Functions

<The previous article in this series | The table of contents of this series | The next article in this series>

A definition of derivation at point of \(C^k\) functions

Topics


About: \(C^\infty\) manifold with boundary

The table of contents of this article


Starting Context



Target Context


  • The reader will have a definition of derivation at point of \(C^k\) functions.

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Definition


For any \(C^\infty\) manifold with (possibly empty) boundary, \(M\), and any point, \(p \in M\), any \(\mathbb{R}\)-linear map, \(D_v: C^k_p (M) \to \mathbb{R}\), that satisfies the Leibniz rule, \(D_v (f_1 f_2) = D_v (f_1) f_2 (p) + f_1 (p) D_v (f_2)\)


2: Note


Strictly speaking, \(C^\infty\) manifold with boundary is not required for \(k \neq \infty\), but just topological manifold with boundary does not suffice, because \(C^k\)-ness is not defined there.


References


<The previous article in this series | The table of contents of this series | The next article in this series>

57: Germ of \(C^k\) Functions at Point

<The previous article in this series | The table of contents of this series | The next article in this series>

A definition of germ of \(C^k\) functions at point, \(C^k_p (M)\)

Topics


About: \(C^\infty\) manifold with boundary

The table of contents of this article


Starting Context



Target Context


  • The reader will have a definition of germ of \(C^k\) functions at point, \(C^k_p (T)\).

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Definition


For any \(C^\infty\) manifold with (possibly empty) boundary, \(M\), and any point, \(p \in M\), the equivalence class of \(\{U_{p, \alpha}, f_\alpha\}\) where \(U_{p, \alpha}\) is any neighborhood of \(p\) and \(f_\alpha\) is any \(C^k\) function, \(f_\alpha: U_{p, \alpha} \to \mathbb {R}\), such that \((U_{p, \alpha_1}, f_{\alpha_1}) \sim (U_{p, \alpha_2}, f_{\alpha_2})\) if and only if there is a neighborhood, \(U_{p, \alpha_3}\), such that \(U_{p, \alpha_3} \subseteq U_{p, \alpha_1} \cap U_{p, \alpha_2}\) and \(f_{\alpha_1} = f_{\alpha_2}\) on \(U_{p, \alpha_3}\)


2: Note


Strictly speaking, \(C^\infty\) manifold with boundary is not required for \(k \neq \infty\), but just topological manifold with boundary does not suffice, because \(C^k\)-ness is not defined there.


References


<The previous article in this series | The table of contents of this series | The next article in this series>

56: Vectors Field Is C^\infty If and Only If Operation Result on Any C^\infty Function Is C^\infty

<The previous article in this series | The table of contents of this series | The next article in this series>

A description/proof of that vectors field is \(C^\infty\) if and only if operation result on any \(C^\infty\) function is \(C^\infty\)

Topics


About: \(C^\infty\) manifold

The table of contents of this article


Starting Context



Target Context


  • The reader will have a description and a proof of the proposition that any vectors field is \(C^\infty\) if and only if its operation result on any \(C^\infty\) function is \(C^\infty\).

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Description


For any \(C^\infty\) manifold, \(M\), any vectors field, \(V\), is \(C^\infty\) if and only if its operation result function on any \(C^\infty\) function is \(C^\infty\).


2: Proof


Let us suppose that its operation result function on any \(C^\infty\) function is \(C^\infty\). At any point, \(p \in M\), there is a chart, \((U_p, x^1, . . ., x^n )\). There, \(V = V^j \frac{\partial}{\partial x^j}\). Each coordinate function, \(x^j: U_p \to \mathbb{R}\), is a \(C^\infty\) function on \(U_p\), and there is a \(C^\infty\) function, \(\tilde{x^j}: M \to \mathbb{R}\), on \(M\) that equals \(x^j\) on a possibly smaller open neighborhood, \(U'_p \subseteq U_p\), of \(p\), by the proposition that for any \(C^\infty\) function on any point open neighborhood of any \(C^\infty\) manifold, there exists a \(C^\infty\) function on the whole manifold that equals the original function on a possibly smaller neighborhood of the point. On \(U'_p\), \(V \tilde{x^j} = V^i \frac{\partial \tilde{x^j}}{\partial x^i} = V^j\), \(C^\infty\) by the supposition, and \(V\) is \(C^\infty\) on \(U'_p\). As \(V\) is \(C^\infty\) on a neighborhood of any point on \(M\), \(V\) is \(C^\infty\) on \(M\).

Let us suppose that \(V\) is \(C^\infty\). At any point, \(p \in M\), there is a chart, \((U_p, x^1, . . ., x^n )\). There, \(V = V^j \frac{\partial}{\partial x^j}\) where \(\{V^i\}\) are \(C^\infty\). For any \(C^\infty\) function, \(f\), on \(M\), on \(U_p\), \(V f = V^j \frac{\partial f}{\partial x^j}\) is \(C^\infty\). As \(V f\) is \(C^\infty\) on a neighborhood of any point on \(M\), it is \(C^\infty\) on \(M\).


References


<The previous article in this series | The table of contents of this series | The next article in this series>

272: Left-Invariant Vectors Field on Lie Group Is C^infty

<The previous article in this series | The table of contents of this series | The next article in this series>

A description/proof of that left-invariant vectors field on Lie group is \(C^\infty\)

Topics


About: Lie group
About: vectors field

The table of contents of this article


Starting Context



Target Context


  • The reader will have a description and a proof of the proposition that any left-invariant vectors field on any Lie group is \(C^\infty\).

Orientation


There is a list of definitions discussed so far in this site.

There is a list of propositions discussed so far in this site.


Main Body


1: Description


For any Lie group, G, any left-invariant vectors field, V, is \(C^\infty\).


2: Proof


There is a \(C^\infty\) curve, \(c: I \rightarrow G\), such that \(c (0) = e\) and \(c' (0) = V_e\). For any \(g \in G\), gc (t) is a \(C^\infty\) curve such that \(gc (0) = g\) and \((gc)' (0) = V_g\), because \((gc)' (0) = l_{g*} c' (0) = l_{g*} V_e = V_g\) by the chain rule for differentiation of map. For any \(C^\infty\) function, f, \((Vf) (g) = V_g f = \frac{df (gc (t))}{dt}|_{0} := A_1\). \(f (gc (t)): I \times G \rightarrow \mathbb{R}, (t, g) \mapsto f (gc (t))\) is a \(C^\infty\) function as a composition of \(C^\infty\) maps, \(I \times G \rightarrow G \times G \rightarrow G \rightarrow \mathbb{R}\), and \(A_1\) is a \(C^\infty\) function with respect to g. As the operation result on any \(C^\infty\) function is \(C^\infty\), V is \(C^\infty\).


References


<The previous article in this series | The table of contents of this series | The next article in this series>

71: Create Any Global UNO Service in Python

<The previous article in this series | The table of contents of this series | The next article in this series>

In order to instantiate the UNO component from a remote programming language environment or to create an artifact like a spread sheet cell function.

Topics


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: the Python programming language

The table of contents of this article


Starting Context



Target Context


  • The reader will know how to create his or her own global UNO service in Python.

Orientation


There is an article on how to create and register any UNO Interface and generate the mapping images.

There is an article on how to build any sample program of this series.

There is an article on how to build an environment for developing UNO programs in Linux or in Windows.


Main Body

Stage Direction
Here are Special-Student-7, Lenard (a Python programmer), and Jane (a Python programmer) in front of a computer.


0: What We Mean by "UNO Service" Here


Special-Student-7
What we mean by "UNO service" here is what is explained in an article.

To state succinctly, UNO service is an item in an UNO objects factory, which is called 'UNO services manager'.

In fact, "service" is a very confusedly and confusingly used term in the official terminology, and we do not mean the 2nd meaning or the 3rd meaning in the official terminology by "UNO service".

If you are wondering how you can create a "service" in the 2nd meaning in the official terminology, I am pretty sure that it is not something you need to create.

Some people may deem "service" in the 3rd meaning in the official terminology handy, but also it is not something you particularly need to create, and as I choose not to create any, I do not explain about it.


1: Why Is a UNO Service Desired?


Special-Student-7
A purpose of creating a UNO service is to instantiate a UNO component from a remote programming language environment.

You know, in the local programming language environment, the UNO component can be instantiated as a normal Python class, but from a remote programming language environment, there must be another way.

Jane
I don't understand what is "local" and what is "remote"; you know, a place is "local" if I'm in it and "remote" if I'm looking at it from afar; nothing is particularly "local" or "remote" by itself; it's just about where I am.

Special-Student-7
You are right. "local" here means the programming language environment in which the UNO component is instantiated; your location does not matter in this case.

Lenard
But my UNO components can be instantiated by one of my UNO objects, local, according to your term.

Special-Student-7
But your 1st UNO object has to come from somewhere, and it typically comes from a UNO services manager, which means that the 1st UNO object comes into being as a UNO service instance.

Lenard
But I can make my Python macro (local) instantiate my Python UNO component, with the macro being called from a remote programming language environment.

Special-Student-7
Ah, you are right; that is a way, certainly.

So, UNO service is a way to instantiate a UNO component from a remote programming language environment, not the only way.

As far as I know, the more prevalent motivation for creating a Python UNO service is to create an artifact that requires the definition of a UNO service

Jane
"an artifact"? I don't understand what you are talking about.

Special-Student-7
"an artifact" is, for example, a spread sheet cell function, which is really a method of a UNO component, which is instantiated as a UNO service by the office main body.

Jane
So, I need to know how to create a UNO service if I need to create a spread sheet cell function . . .

Special-Student-7

2: A Note: We Are Creating a Global UNO Service


Special-Student-7
Although not every UNO service is a global UNO service, when we talk about UNO service in this article, we are always talking about global UNO service.

Lenard
Oh, cruel world! Non-global UNO services are being ignored!

Special-Student-7
Any non-global UNO service is only for internal use by the office product, as far as I know, and so, you will probably have no opportunity to create a non-global UNO service or even opportunity to directly use a non-global UNO service.

Lenard
Won't I?

Special-Student-7
Probably not. So, note that when I talk about UNO service without any particular specification in this series, it is about global UNO service.


3: Create the UNO Service



3-1: Prepare the UNO Component


Special-Student-7
The UNO component has to satisfy a certain prerequisite for it to be registered as a UNO service.

Namely, it has to implement the UNO interface, 'com.sun.star.lang.XServiceInfo', like this.

@Python Source Code
from typing import Any
from typing import List
from typing import Set
from typing import cast
from collections import OrderedDict
import uno
from com.sun.star.lang import IllegalArgumentException
from com.sun.star.lang import XServiceInfo
from com.sun.star.uno import XComponentContext
from unohelper import Base as UnoBase
XTest1: Any = uno.getClass ("theBiasPlanet.unoDatumTypes.tests.XTest1")

class PythonTest1UnoComponent (UnoBase, XServiceInfo, XTest1):
	c_thisClass: type = None
	c_unoServiceNames: Set [str] = set ()
	c_unoCompoundInterfaceNames: Set [str] = set ()
	# # Add UNO service names Start
	c_unoServiceNames.add ("theBiasPlanet.tests.PythonTest1UnoComponent")
	# # Add UNO service names End
	# # Add UNO compound interface names Start
	# # Add UNO compound interface names End
	
	@staticmethod
	def setThisClassToGlobalUnoServicesProvider (a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap: "OrderedDict [str, OrderedDict [type, Set [str]]]")-> None:
		l_implementationClassToUnoServiceNamesMap: "OrderedDict [type, Set [str]]" = OrderedDict ()
		l_implementationClassToUnoServiceNamesMap.update ( {PythonTest1UnoComponent.c_thisClass: PythonTest1UnoComponent.c_unoServiceNames})
		a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap.update ( {"{0:s}.{1:s}".format (PythonTest1UnoComponent.c_thisClass.__module__, PythonTest1UnoComponent.c_thisClass.__name__): l_implementationClassToUnoServiceNamesMap})
	
	def __init__ (a_this: "PythonTest1UnoComponent", a_underlyingUnoObjectsContextInXComponentContext: XComponentContext, a_message: str) -> None:
		a_this.i_underlyingRemoteUnoObjectsContextInXComponentContext: XComponentContext
		# # Add the other member variables Start
		a_this.i_message: str
		# # Add the other member variables End
		
		UnoBase.__init__ (a_this)
		a_this.i_underlyingRemoteUnoObjectsContextInXComponentContext = a_underlyingUnoObjectsContextInXComponentContext
		a_this.i_message = None
		
		# initialization Start
		a_this.i_message = a_message
		if a_this.i_message is None:
			raise IllegalArgumentException ("The first argument can't be null.")
		# initialization End
	
	def __del__ (a_this: "PythonTest1UnoComponent") -> None:
		None
	
	def getImplementationName (a_this: "PythonTest1UnoComponent") -> str:
		return "{0:s}.{1:s}".format (PythonTest1UnoComponent.c_thisClass.__module__, PythonTest1UnoComponent.c_thisClass.__name__)
	
	def supportsService (a_this: "PythonTest1UnoComponent", a_unoCompoundInterfaceName: str) -> bool:
		return a_unoCompoundInterfaceName in PythonTest1UnoComponent.c_unoCompoundInterfaceNames
	
	def getSupportedServiceNames (a_this: "PythonTest1UnoComponent") -> List [str]:
		l_numberOfItems: int = len (PythonTest1UnoComponent.c_unoCompoundInterfaceNames)
		l_unoCompoundInterfaceNamesArray: List [str] = [None] * l_numberOfItems
		l_itemIndex: int = 0
		l_unoCompoundInterfaceName: str = None
		for l_unoCompoundInterfaceName in PythonTest1UnoComponent.c_unoCompoundInterfaceNames:
			l_unoCompoundInterfaceNamesArray [l_itemIndex] = l_unoCompoundInterfaceName
			l_itemIndex = l_itemIndex + 1
		return l_unoCompoundInterfaceNamesArray
	
	# # Add the methods of the implemented UNO interface Start
	def test1 (a_this: "PythonTest1UnoComponent", a_name: str)-> str:
		if a_name is None:
			raise IllegalArgumentException ("The first argument can't be null.")
		return "{0:s}, {1:s}!".format (a_this.i_message, a_name)
	# # Add the methods of the implemented UNO interface End
	
	# # Add other methods Start
	# # Add other methods End

PythonTest1UnoComponent.c_thisClass = PythonTest1UnoComponent

Lenard
. . . Of course . . .

Special-Student-7
Of course, you do not need to implement it exactly like that: you need to implement the constructor and those 'XServiceInfo' methods somehow appropriately.

Lenard
"somehow"? Whathow?

Special-Student-7
The constructor has to have that 'XComponentContext' argument there and have the appropriate initialization arguments.

Python UNO is special in not respecting implementing the 'com.sun.star.lang.XInitialization' UNO interface.

Lenard
Huh?

Special-Student-7
In Java UNO and C++ UNO, the UNO service UNO component has to implement the 'com.sun.star.lang.XInitialization' UNO interface, and the initialization arguments are passed into the 'initialize' method of the UNO interface.

In Python UNO, the initialization arguments are passed into the constructor.

Lenard
What if there are multiple arguments?

Special-Student-7
The constructor has to have multiple arguments.

Lenard
So, the number of arguments has to be predetermined . . .

Special-Student-7
Yes. The situation is different from for the other UNO programming languages, in which the arguments are passed as an array.

Lenard
Well . . .

Special-Student-7
"service" for "supportsService" and "getSupportedServiceNames" are basically not UNO service, but "service" in the 2nd meaning in the official terminology.

Jane
So, what "service"s in the 2nd meaning does the UNO component need to support?

Special-Student-7
If the UNO component is of a certain kind of artifacts, the kind requires the UNO component to support certain "services"; otherwise, the UNO component does not need to support any "service", basically.

Jane
How about non-"basically"?

Special-Student-7
As "service" is so jumbled up as a concept, sometimes, something that is basically a "service" in the 2nd meaning in the official document is opportunistically abused also in the meaning of UNO service and vice versa. I have not noticed any problem in not supporting the UNO service name in those 2 methods, but I said "basically" just in case. In fact, there will be no practical problem in supporting the UNO service name there, which you may choose.

Jane
Ah, a grown-up talk.

Special-Student-7
Managing the UNO service information in like "c_unoServiceNames" is my contrivance to not scatter such information around methods, which you do not particularly follow; and the "setThisClassToGlobalUnoServicesProvider" method is for injecting the information into the global UNO services provider, which will be created next, in order to avoid doubly writing the information in the global UNO services provider, so you do not particularly need to have the method if you want to doubly write.


3-2: Create a Global UNO Services Provider


Special-Student-7
We need to create a global UNO services provider, which is required for the UNO services to be instantiated.

In fact, Python global UNO services provider is not a class as Java global UNO services provider is, but is a module that has a 'g_ImplementationHelper' 'unohelper.ImplementationHelper' object.

Lenard
Um? So, is it just a matter of having a single object?

Special-Student-7
Yes, it is.

Lenard
Then, can't I just make the UNO component have the object?

Special-Student-7
You could, but while there may be multiple UNO components, which one should have the object?

Lenard
Any arbitrary one should.

Special-Student-7
I do no approve such asymmetric-ness.

Lenard
But I have only one UNO component.

Special-Student-7
Even if you happen to have only one UNO component, the information structure would be already skewed, because the object does not really belong there.

Lenard
Would it?

Special-Student-7
Anyway, this is a global UNO services provider, followed by my utility class.

@Python Source Code
from typing import Any
from typing import Set
from collections import OrderedDict
import uno
import unohelper
from theBiasPlanet.unoUtilities.servicesHandling.GlobalUnoServicesProviderUtility import GlobalUnoServicesProviderUtility
from theBiasPlanet.tests.models.PythonTest1UnoComponent import PythonTest1UnoComponent

c_implementationClassNameToImplementationClassToUnoServiceNamesMapMap: "OrderedDict [str, OrderedDict [type, Set [str]]]" = OrderedDict ()
PythonTest1UnoComponent.setThisClassToGlobalUnoServicesProvider (c_implementationClassNameToImplementationClassToUnoServiceNamesMapMap)
g_ImplementationHelper: Any = unohelper.ImplementationHelper () # this variable has to be of the name, because the office product searches for it.
GlobalUnoServicesProviderUtility.setUpUnoServiceRegistrationHelper (g_ImplementationHelper, c_implementationClassNameToImplementationClassToUnoServiceNamesMapMap)


@Python Source Code
from typing import Any
from typing import Set
from collections import OrderedDict

class GlobalUnoServicesProviderUtility:
	@staticmethod
	def setUpUnoServiceRegistrationHelper (a_unoServiceRegistrationHelper: Any, a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap: "OrderedDict [str, OrderedDict [type, Set [str]]]")-> None:
		l_implementationClassName: str = None
		l_implementationClassToUnoServiceNamesMap: "OrderedDict [type, Set [str]]" = None
		l_implementationClass: type = None
		l_UnoServiceNames: Set [str] = None
		for l_implementationClassName, l_implementationClassToUnoServiceNamesMap in a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap.items ():
			for l_implementationClass, l_UnoServiceNames in l_implementationClassToUnoServiceNamesMap.items ():
				break
			a_unoServiceRegistrationHelper.addImplementation (l_implementationClass, l_implementationClassName, tuple (l_UnoServiceNames))


I have prepared that utility class, "GlobalUnoServicesProviderUtility", because it would be uneconomical to write that code into each global UNO services provider, but if you will, of course, you can be uneconomical.

As I said in the previous sub section, the information of the UNO service is injected into the global UNO services provider by the "setThisClassToGlobalUnoServicesProvider" method.

Jane
Well, you seem to have made the code more complicated than it should be: you can make the "setThisClassToGlobalUnoServicesProvider" method put the information directly into the 'g_ImplementationHelper' object, then, such a utility class will be unnecessary.

Special-Student-7
Ah, you are right, actually.

Jane
"you are right"? Just like that?

Special-Student-7
I mean, I understand what you mean: your code will be much shorter as a whole. My code is like that because I thought that each UNO component was better not depending on the implementation of the 'g_ImplementationHelper' object.


3-3: Create the Extension Configuration Files


Special-Student-7
We are going to register the UNO service via a LibreOffice or Apache OpenOffice extension, and we need some configuration files for that.

Lenard
I didn't know I was going to create an "extension".

Special-Student-7
Sir, it is as easy as creating some configuration files and archiving the ingredients in a ZIP file.

Lenard
I see.

Special-Student-7
We are creating that "UnoServiceComponents.xml" file, like this.

@XML Source Code
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://openoffice.org/2010/uno-components">
	<component loader="com.sun.star.loader.Python" uri="Scripts/python/theBiasPlanet/tests/globalUnoServicesProvider/TestsGlobalUnoServicesProvider.py">
		<!-- # Add UNO component class names -->
		<implementation name="theBiasPlanet.tests.models.PythonTest1UnoComponent.PythonTest1UnoComponent">
			<!-- # Add UNO service names Start -->
			<service name="theBiasPlanet.tests.PythonTest1UnoComponent"/>
			<!-- # Add UNO service names End -->
			<!-- # Add UNO compound interface names Start -->
			<!-- <service name="???"/> -->
			<!-- # Add UNO compound interface names End -->
		</implementation>
	</component>
</components>

Jane
The tag name is "component", but it does not correspond to a UNO component, right?

Special-Student-7
No, it does not. "component" could mean anything in the lax official terminology, and now, "component" seems to mean the set of possibly multiple Python UNO services defined in the extension.

Jane
Anyway, that is how the global UNO services provider is recognized by the office product.

Special-Student-7
Note that the UNO service name should be specified there as well as "service" in the 2nd meaning names should.

Lenard
Huh? As those 2 methods do not need to support the UNO service name, why does the configuration file need the UNO service name?

Special-Student-7
You have to endure such inconsistency; "service" is really jumbled up in the code, not just in the documentation.

Anyway, we need to create also "manifest.xml" of course, but I do not show it here, because it is exactly as in the article.


3-4: An Aside: What Are Not Necessary


Lenard
I need to create the service IDL file, don't I?

Special-Student-7
No, because any service IDL file is for creating a "service" in the 2nd meaning or "service" in the 3rd meaning in the lax official terminology, not for creating a UNO service.

You will never need to create any "service" in the 2nd meaning; you, a Python programmer, cannot use any "service" in the 3rd meaning, because there is no tool for generating the Python image of it, although a Java programmer can use it to instantiate your Python UNO service.

Lenard
But they gives me some peace of mind.

Special-Student-7
Well, why will you not just have the peace of mind without the bother of creating meaningless things?


3-5: Create the Extension File


Special-Student-7
Now, we are going to create the extension file.

I do not need to explain how, because it has been already detailed in a previous article.


3-6: Register the Extension


Special-Student-7
We are going to register the extension.

It can be done via the GUI menu item "Tools" -> "Extension Manager...".

Or you can use the 'unopkg' command, if your build script wants to register the extension, like this.

@bash or cmd Source Code
unopkg add -f -v %the extension file path%

Note that LibreOffice or Apache OpenOffice instance is supposed to have been shut down before the command.


3-7: Setting the Additional Modules Paths into the Office Product


Special-Student-7
While we have created the UNO component and the global UNO services provider in 2 different modules, in fact, that structure requires a configuration, without which the global UNO services provider would not be able to import the UNO component.

In fact, the path of the extension Python base directory is not automatically set into the office product.

Lenard
Huh? Ridiculous! Then, any macro in my extension can't import any module in the same extension!

Special-Student-7
It cannot, without the configuration, as a matter of fact.

Lenard
Then, I have to make the macro self-sufficient, pushing all the depended code into the macro module, foolish!

Special-Student-7
Yes, unless the configuration is in place, as is explained in a section of another article.

Lenard
I think that the configuration should be incorporated into the office product.

Special-Student-7
Please advocate the cause.

If you do not do the configuration, the UNO component will have to be put into the global UNO services provider module.

And if your UNO service uses some libraries made by you or otherwise, the paths of the libraries will have to be set into the office product.

Lenard
Can't I just register the libraries into the Python product itself?

Special-Student-7
You could; for example, any library installed by 'pip' is certainly a part of the Python product, and their paths do not have to be explicitly set into the office product.

But you usually do not register a library made by you into the Python product, do you?

Lenard
Not, if it is not necessary.

Jane
I can copy the libraries into the extension, after the configuration has been in place, can't I?

Special-Student-7
Yes, you can, but as copying the libraries into multiple extensions makes the libraries redundant, I would rather locate the libraries in the local file system and set the paths into the office product by the way explained in another section of the article, letting the libraries be shared by multiple extensions and others whatever.

Jane
Hmm.


4: Instantiate the UNO Service


Special-Student-7
The UNO service can be instantiated, as any built-in global UNO service can.

Jane
Let me see how the above UNO service can be instantiated.

Special-Student-7
For example, this is a Python macro.

@Python Source Code
from typing import Any
from typing import cast
import uno
~
from com.sun.star.script.provider import XScriptContext
from com.sun.star.uno import XComponentContext
XTest1: Any = uno.getClass ("theBiasPlanet.unoDatumTypes.tests.XTest1")

XSCRIPTCONTEXT: XScriptContext
c_underlyingRemoteUnoObjectsContextInXComponentContext: XComponentContext = XSCRIPTCONTEXT.getComponentContext ()
~
c_pythonTest1UnoComponent: "XTest1" = cast (XTest1, c_underlyingRemoteUnoObjectsContextInXComponentContext.getServiceManager ().createInstanceWithArgumentsAndContext ("theBiasPlanet.tests.PythonTest1UnoComponent", ["Hello"], c_underlyingRemoteUnoObjectsContextInXComponentContext))
~

def test1 () ->None:
	~
	c_pythonTest1UnoComponent.test1 ("dude")
	~


Jane
Hmm, the Python class can be instantiated from any remote UNO programming language environment, now.


5: Here Is a Workable Sample


Special-Student-7
Here is a workable sample extension.

How to build the sample project is explained in an article.

The main project is 'hiUnoExtensionsUnoExtension', which uses the additional UNO datum types project and some utility projects.

The UNO datum types merged file has to be registered into the office product according to the way 1) stated in a previous article.

And the paths of the utility Python code base directories ('coreUtilitiesToBeDisclosed/target' and 'unoUtilitiesToBeDisclosed/target') have to be set into the office product according to the way mentioned in a previous section.

Lenard
I do not expect the uneducated users to be able to do such settings, as the extension is supposed to be distributed to such users.

Special-Student-7
You can un-necessitate the setting of the UNO datum types merged file by putting the UNO datum types merged file into the extension by the way 2) stated in a previous article, but the situation concerning the utility libraries is as is stated in the previous section.

Lenard
But it is meaningless if the users can't do the settings.

Special-Student-7
That is a matter of how you prepare an installer that automates the settings, and if your UNO component is self-sufficient, you will not need to worry about libraries.

Lenard
Well, I can prepare the installer, as it has to just copy some files, supposing that the office product directory path is pre-known.

Jane
Your installer can just ask the user the directory path.

Special-Student-7
Anyway, the extension should have registered a tool buttons group, from which the testing macro can be called.

Lenard
"buttons"? Will I get multiple buttons?

Special-Student-7
You will have only one for-Python-UNO-service button; the other 2 buttons are for a Java UNO service and for a C++ UNO service, which will be unusable if you have disabled Java and C++ for building the sample project.


References


<The previous article in this series | The table of contents of this series | The next article in this series>