<The previous article in this series | The table of contents of this series | The next article in this series>
We Created a UNO Extension Project Skeletons (and UNO Additional Data Types Project Skeletons) Maker
About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: Java Programming Language
Here are -Hypothesizer and -Rebutter sitting in front of a computer screen in a room on a brook among some mountains on the Bias planet.
We already know the building blocks of UNO extension projects and the inside structures of those building blocks, but it's cumbersome to make those building blocks: we have to make each name reflected in several places.
What do you mean by 'each name'?
There are some names that characterize a UNO extension, for example, global UNO service names that are registered by the UNO extension.
And in how many places, does a global UNO service name have to be reflected?
Well, . . . four places as it has to be written in the UNO component, in the UNO components setting file, and in the 'global UNO service'-specific service instances factory, and has to be reflected as the path of the 'global UNO service'-specific service instances factory source file.
If we happen to make a mistake in one of those places, our program won't work, and we will have to check those places one by one . . .
Hmm, considering the frequency of creating UNO extensions, it doesn't seem to be an intolerable task to do.
I don't say that it's intolerable, but I feel somewhat disconsolate in doing such a routine chore.
That's too bad, feeling disconsolate in such a thing.
Anyway, we are going to create a UNO extension skeletons maker, which enables us to avoid such routine chores.
As a prophylactic for your disconsolation . . .
The same with the previous scene.
What is the design of our UNO extension project skeletons maker?
There are some parameters we have to specify for a UNO extension.
Of course.
We will specify those parameters on a spread sheet, and our UNO extension project skeletons maker will make the building blocks of the UNO extension based on those parameters.
What are those parameters?
Before I cite them, I would say that you wouldn't understand them if you don't understand basic concepts of UNO.
Of course. . . . Obviously, we have to build up understandings beginning with basic concepts: I don't demand any thing explained while grudging due efforts, do I?
I didn't say you do: it was just showing the reference where you should go if something is unclear to you.
All right.
These are the parameters that have to be specified for each project:
- project name = the name of the project directory (spaces aren't supposed to be included in the name)
- the target name
- defined UNO interface names as pairs of a package name and a relative core name (optional)
- super UNO interface names, with each of which associated with a defined UNO interface
- the Java package name of all the defined UNO components = the module name of all the defined global UNO services
- defined UNO component relative core names
- implemented UNO interface names, with each of which associated with a defined UNO component
- defined global UNO service relative core names, with each of which associated with a defined UNO component (optional)
- defined 'global UNO service'-specific service instances factory names as pairs of a package name and a relative core name (optional)
- return type UNO interface names, with each of which associated with a defined 'global UNO service'-specific service instances factory (only one for a defined 'global UNO service'-specific service instances factory)
- included jar path expressions (optional)
- other classes path expressions (optional)
- referenced project path expressions (optional and effective only for Gradle projects)
Hmm, there are many.
It's inevitable: I enlisted only independent parameters; we can't spare any parameter that can't be derived from other parameters, logically speaking.
What are being noted 'optional' are optional . . .
For example, if we are going to create UNO components implementing existing UNO interfaces, we don't need to define any new UNO interface.
In that case, of course, any super UNO interface name isn't necessary, although they aren't noted as 'optional'.
As for things that are noted as 'with each of which associated with <something>', they are noted as 'optional' only when there can be none of them for a <something>.
So, if there is a defined UNO interface, there must be at least one super UNO interface name for the defined UNO interface, while even if there is a defined UNO component, there doesn't have to be any defined global UNO service relative core name for the defined UNO component.
Exactly: not all the UNO components have to be registered as UNO services.
The description, 'the Java package name of all the defined UNO components = the module name of all the defined global UNO services', seems to mean that the Java packages of all the defined UNO components and the modules of all the defined global UNO services have to be the same . . .
That's our convention. Of course, defined UNO components can have different Java package names according to the UNO specifications, but we don't see any necessity to let them do so, and forcing that restriction makes the project more visible, I think.
More 'visible'?
I mean, the structure of the project will be more easily understood at a glance.
Hmm, having a base name for UNO component Java packages and UNO service modules seems fine, but if we begin to have many UNO components in a project, we may begin to feel a necessity to classify them in sub packages.
Ah, . . . you are right, but at this point, I don't imagine that we will have many UNO components in a UNO extension project, in the near future. Giving more flexibility is good, but it can complicate the specification of parameters. So, I would like to stick to the design above, at least for now.
All right. I understand that you are supposing to have multiple UNO extension projects than have multiple sub packages in a UNO extension project.
And what does 'relative core' mean in, for example 'defined UNO component relative core names'?
Ah, 'relative name' means a full class name minus the package part.
So, for a full class name, 'java.lang.String', the relative name is . . .
'String'. I know that a class relative name is usually called just a 'class name' while a full class name also tends to be called just a 'class name', but as I have a policy of avoiding ambiguous expressions, I must distinguish one from the other. An option is to use 'class name' and 'full class name', but I happened to adopt 'class relative name' and 'class name'.
So, a 'class name' is always a full class name, at least in this context?
That is my intention.
What does 'core name' mean?
I'm going to inflict some name conventions: any defined UNO component name has to end with 'UnoComponent', for example. A core name is a name minus the mandatory part.
So, if a relative core name of a UNO component is 'Test1', the relative name is 'Test1UnoComponent', for example?
Yes. . . . I know I'm a little, or much, obsessed with describing things unambiguously. Anyway, when I am told to specify a class name as a parameter, I have to be told whether it is a full class name or a relative class name, and if it is a core name, I have to be told so.
Well, to state things explicitly is the first step of avoiding fallacies . . .. And in order to state things explicitly, descriptions can't avoid becoming lengthy, to a certain degree.
I know that the majority of people love simplified, inaccurate descriptions, but my aim is to be accurate, not to pander to the majority of people . . .
Anyway, to add some notes, the target name is used as the base of some file names, for example the jar file.
And note that I used the word 'expression' as in 'included jar path expressions'.
I noted, but what does it mean?
It means that it isn't the contents of a plain literal, but an expression that specifies a path, for example, 'LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/unoil.jar"'.
So, if a term isn't enclosed in double-quotes, the term will be interpreted as a variable, not the contents of a literal string?
Exactly.
In the second UNO extension sample, we have separated UNOIDL files to another project (we will call such a project a 'UNO additional data types project'). How can we make, say UNO interface source file skeletons, in a UNO additional data types project?
Ah, a UNO additional data types project isn't a UNO extension project, and according to the title of 'UNO Extension Project Skeleton Maker', it comes that it isn't in the scope of our tool . . ., but it would be sad if we couldn't make UNO interface source file skeletons because it's a UNO additional data types project, not a UNO extension project.
The logic of making UNO interface source file skeletons will be the same whether in a UNO extension project or in a UNO additional data types project, won't it?
It will. So, our UNO extension project skeleton maker will be really a UNO extension project skeletons and UNO additional data types project skeletons maker.
In fact, it can be a more general project skeletons maker.
It can, but at this point, I don't see significant merits in making a Java project by our tool, and calling our tool just a project skeletons maker would make it obscure: what's special about it?
When we make a UNO additional data types project, the set of parameters that have to specified is different from the one shown above, isn't it?
Of course. It is like this.
- project name = the name of the project directory (spaces aren't supposed to be included in the name)
- the target name
- defined UNO interface names as pairs of a package name and a relative core name (optional)
- super UNO interface names, with each of which associated with a defined UNO interface
- defined 'global UNO service'-specific service instances factory names as pairs of a package name and a relative core name (optional)
- return type UNO interface names, with each of which associated with a defined 'global UNO service'-specific service instances factory (only one for a defined 'global UNO service'-specific service instances factory)
You said, "parameters that have to be specified for each project", which seems to imply that there are also some parameters that don't have to be specified for each project.
Yes, it does. There is a parameter that is common to projects: the development base directory path.
How about relative paths of some directories in a project, for example the relative path of the Java source files base directory?
Actually, they are hard-coded in a source file. If we want to change them, we can do so by modifying the source file. As our Gradle build scripts and Ant build files are based on our common Gradle build scripts and Ant build files, and those relative directory paths are written in those common files, parameterizing those relative directory paths just in this tool didn't make much sense to me.
<The previous article in this series | The table of contents of this series | The next article in this series>