Information
We are currently investigating an issue with the editor of some pages. Please save your work and avoid to create new pages until this banner is gone.
...
...
The
...
purpose
...
of
...
this
...
document
...
is
...
to
...
give
...
a
...
practical
...
introduction
...
to
...
writing
...
Java
...
components
...
for
...
ALMA
...
software,
...
using
...
the
...
ACS
...
container/component
...
framework.
...
You
...
should
...
have
...
read
...
the
...
section
...
on
...
Technical
...
Architecture
...
in
...
[
...
1
...
]
...
or
...
have
...
learned
...
otherwise
...
about
...
the
...
concepts
...
of
...
container/component
...
and
...
XML
...
binding
...
classes
...
to
...
be
...
used
...
for
...
ALMA
...
software.
...
You
...
should
...
also
...
be
...
familiar
...
with
...
the
...
ALMA
...
build
...
environment
...
(see
...
[8
...
]),
...
even
...
though
...
a
...
few
...
things
...
are
...
explained
...
redundantly
...
in
...
this
...
tutorial.
...
While
...
describing
...
the
...
steps
...
involved
...
in
...
developing
...
two
...
sample
...
components,
...
I
...
will
...
try
...
to
...
provide
...
information
...
beyond
...
the
...
scope
...
of
...
the
...
demo
...
components
...
in
...
order
...
to
...
help
...
using
...
the
...
framework
...
for
...
concrete
...
ALMA
...
subsystem
...
development.
...
However,
...
this
...
is
...
not
...
a
...
concept
...
or
...
design
...
document
...
for
...
the
...
respective
...
parts
...
of
...
ACS.
...
It
...
should
...
help
...
you
...
to
...
get
...
started
...
nonetheless.
...
The
...
Java
...
container/component
...
model
...
is
...
fully
...
integrated
...
in
...
ACS.
...
It
...
is
...
meant
...
to
...
be
...
used
...
by
...
ALMA
...
subsystems
...
or
...
the
...
parts
...
of
...
them
...
that
...
don’t have
...
real-time
...
requirements
...
and
...
don’t directly
...
control
...
hardware
...
devices.
...
This document no longer maintains a separate section for abbreviations. Please use the ALMA software glossary [13].
...
Wiki Markup |
---|
\\
This document no longer maintains a separate section for abbreviations. Please use the ALMA software glossary \[13\].
\\ |
...
...
...
...
Readers should feel very much encouraged to follow at their computers the steps described in the chapters below, switching between this tutorial and the real software.
...
...
The
...
Java
...
parts
...
of
...
the
...
ACS
...
framework
...
were
...
developed
...
using
...
the
...
Eclipse
...
IDE.
...
Eclipse
...
is
...
not
...
one
...
of
...
the
...
“official” ALMA
...
standards,
...
but
...
a
...
majority
...
of
...
ALMA
...
developers
...
finds
...
it
...
so
...
helpful
...
that
...
I
...
like
...
to
...
recommend
...
getting
...
it.
...
You
...
can
...
download
...
Eclipse
...
for
...
free
...
from
...
[10
...
].
...
The
...
latest
...
milestone
...
build
...
is
...
usually
...
fine,
...
but
...
special
...
plugins
...
may
...
require
...
to
...
use
...
a
...
released
...
version.
...
We have started a description on how to configure Eclipse to work well together with the ALMA build system [11]. It’s expected to grow, feedback is welcome. As background information, notes from a presentation of Eclipse given at ESO are also available on that page.
...
The ACS release (currently ACS 4.1.1) contains source code inside the delivered jar files, both for the implementation of the container, compiled IDL files etc, as well as for the examples used in this tutorial.
Automatically generated documentation and the source code for the examples can also be found online at
http://www.eso.org/projects/alma/develop/acs/OnlineDocs/jcontexmpl/doc/html/index.html.
A live web-based CVS view for all relevant ACS modules is at httpat https://websqabitbucket.hqsco.esoalma.org/bin/viewcvs.cgi/ACScl/projects/ASW/repos/acs/browse/LGPL/CommonSoftware/ .
The modules that play a major role in the Java container/component part of ACS are listed below in compile order, together with the jar files they produce.
...
/doc |
| Nothing too exciting since the API documentation is generated by the Makefile and is not supposed to be checked in. |
/idl | HelloDemo.idl | definition of the HelloDemo component used in this tutorial |
| XmlComponent.idl | definition of the XmlComponent component used in this tutorial |
| EventComponent.idl | other demo components not considered in this tutorial |
| ErrorSystemComponent.idl | definition of errors with certain types and codes, see [6]]]></ac:plain-text-body></ac:structured-macro> |
/include |
| not used, but required by build system |
/lib | jcontexmpl.jar | compilation of /src, produced by running the Makefile in /src |
| HelloDemo.jar | compilation of /idl/HelloDemo.idl |
| XmlComponent.jar | compilation of /idl/XmlComponent.idl |
| other .jar, .so, .a files | output of Java/C++ IDL compilation of the IDL files |
/object |
| not used, but required by build system |
/src |
| demo components and test clients |
/test |
| tests internal to ACS that use the demo components |
...
To compile and run the software, you need a current installation of ACS. The basic concepts for Java components have not changed since ACS 3.0 though.
...
...
The /src and /test directories each contain a Makefile. The command
make clean all
will compile IDL and Java code and pack the results into jar files.
make install
will copy IDL, schema, and jar files to the respective sub-directories of your INTROOT directory so that they are available for other modules.
To learn about using the make system, refer to "man acsMakefile" and "man javaMakefile".
...
To run the container, you must first start the ACS services & manager. Either use the graphical ACS Command Center (see [5]), or the command
acsStart
Make sure your ACS_CDBvariable points to the CDB installation that you want to use. You find a CDB suitable for the examples under jcontexmpl/test in CVS. You could either use that CDB directly, or merge the entries from Components.xml into your
...
$ACS_CDB/CDB/MACI/Components/Components.xml.
...
To
...
run
...
the
...
container
...
on
...
the
...
same
...
machine
...
where
...
the
...
Manager
...
runs,
...
use
...
the command
acsStartContainer –java <containername>
...
For
...
cases
...
where
...
the
...
manager
...
runs
...
on
...
a
...
different
...
machine,
...
please
...
refer
...
to
...
[3
...
]
...
(
...
“FAQGeneralCompContainerOptions”).
...
To
...
terminate
...
a
...
Java
...
container,
...
you
...
can
...
use
...
the
...
command
...
line
...
acsStopContainer <containername>
...
or
...
the
...
brute-force
...
approach
...
with
...
Ctrl-C
...
on
...
the
...
container
...
console;
...
in
...
this
...
case
...
the
...
Manager
...
will
...
attempt
...
to
...
reload
...
components
...
in
...
that
...
container
...
next
...
time
...
the
...
container
...
runs.
...
The
...
rest
...
of
...
ACS
...
you
...
terminate
...
with
acsStop (or killACSif all else fails).
...
...
...
The
...
recommended
...
method
...
is
...
Java
...
remote
...
debugging,
...
which
...
is
...
described
...
in
...
the
...
ACS
...
FAQs
...
[3
...
]
...
under
...
“How do
...
I
...
debug
...
my
...
components?
...
”.
...
Windows aficionados can run the Java container with its components (or just a client application that accesses components) on a Windows machine that has a network connection to another machine where the rest of ACS is running. Different subversions of JDK 1.4 have worked fine on Windows.
The build process (make) is not available under Windows. Assuming you have ACS installed on a Linux machine, you should keep your source code there, and mount the directories on Windows, e.g. using Samba The ACS FAQ will describe the setup in more detail.. The initial compilation must be done on Linux to compile IDL etc. Subsequent plain Java compilations can then be done from Windows.
There is an issue with CR/LF line termination: if you get ASCII sources from CVS on Windows, they come with Windows line breaks; the build process runs on Linux though, and a few tools will fail without telling you why. The Makefile itself and the IDL files are affected. In case of doubt, run dos2unix on them, e.g.
~/CVSPRJ/ACS/jcontexmpl/src 1001 > dos2unix Makefile
...
By default, log messages are sent to the local console and to the central ACS logger. There they simply get absorbed in the void if you don't register for them. For example,
acsStartLoggingClient | tee mylog.xml
will send all logs messages to the file mylog.xml and also to the console where you typed the command.
To adjust the log levels that get through, you may provide your own Java logging properties file. It must be compliant to the JDK 1.4 logging spec. Refer to the FAQ for the details. As a template for the properties file, you could use almalogging.properties from acsjlog/src.
There is also a graphical application "LoggingClient" that you can start with the command jlog
...
jlog
During the design of your ALMA subsystem, you should partition your software into one or preferably several components The "subsystem master component" concept may be included in this tutorial in the future. A component will be the smallest chunk of software that can be deployed separately, e.g. in its own process or even on its own machine. Guidelines are that a component should be small enough to be functionally cohesive (having exactly one functional interface with related methods), but large enough to keep the number of components sufficiently small. Typically, a component will be made up of several Java classes, and a subsystem might consist of a handful of components.
There can be components that will be used by other subsystems, while other components are only used internally by the subsystem. In either case, the functional interface must be specified as CORBA IDL.
The example components that we'll look at in the tutorial are not jewels of OO design, but they are meant to illustrate the steps involved to get to an implementation. The detailed motivation for all methods used in the interfaces is described in the next section about IDL.
We will work withwith
Wiki Markup |
---|
\\
The components and their containers can be pictured as follows, with the "antennas" sticking out on top being the functional interfaces.
\\
\\
\\
The two Java components, HelloDemo and XmlComponent, can either run collocated inside one Java container as shown, or run in separate Java containers. The Java container is drawn as a closed box to indicate that it works as a "tight container" (cf. \[1\]), intercepting all functional calls to any of its components, in addition to starting/stopping the components and providing explicit services to them.
\\
The Java components can talk with, say, a C++ component "otherComp", which must run inside a C++ container ("other Container"). That container is drawn open to indicate that it is a "porous" kind of container which only takes care of starting/stopping the components, but does not intercept functional calls on the running components.
\\
The ACS containers use CORBA and the ACS services, the ACS Manager, and the Configuration Database. The Manager itself also uses the CDB.
\\ |
...
The components and their containers can be pictured as follows, with the “antennas” sticking out on top being the functional interfaces.
The two Java components, HelloDemo and XmlComponent, can either run collocated inside one Java container as shown, or run in separate Java containers. The Java container is drawn as a closed box to indicate that it works as a “tight container” (cf. [1]), intercepting all functional calls to any of its components, in addition to starting/stopping the components and providing explicit services to them.
The Java components can talk with, say, a C++ component “otherComp”, which must run inside a C++ container (“other Container”). That container is drawn open to indicate that it is a “porous” kind of container which only takes care of starting/stopping the components, but does not intercept functional calls on the running components.
The ACS containers use CORBA and the ACS services, the ACS Manager, and the Configuration Database. The Manager itself also uses the CDB.
...
A component's functional interface must be specified as an interface in CORBA's Interface Definition Language (IDL). An IDL file may contain more than one interface. The Java container framework does not require further restrictions Currently there is a problem with IDL attributes which will be fixed later. on the usage of the more exotic IDL constructs beyond what ACS already mandates for the definition of C++ components.
Using the ALMA directory structure, you should put IDL files in the <xxxx>/idl directory of your module. Our HelloDemo component is defined in jcontexmpl/idl/HelloDemo.idl.
Let's look at the listing of HelloDemo.idl with line-by-line explanations.
01 #ifndef
Code Block | ||||
---|---|---|---|---|
| ||||
#ifndef _HELLODEMO_IDL |
...
_ #define _HELLODEMO_IDL |
...
_ #include <acscomponent.idl> |
...
#pragma prefix "alma" |
...
module demo { // a very simple component interface HelloDemo : ACS::ACSComponent { string sayHello(); string sayHelloWithParameters(in string inString, inout double inoutDouble, out long outInt); }; }; #endif |
1, 2, 16 | Standard include guard to avoid multiple inclusions of this IDL file |
3 | Mandatory include of acscomponent.idl (see line 9) |
4 | Standard CORBA directive that affects generated Java classes At least for what we care about here; primarily the prefix controls the CORBA repository ID.. The prefix pragma must come after the include statements (this restriction might be lifted in the future, but for now the TAO IFR would have a problem otherwise.) |
6 | Declaration of the CORBA module "demo". A module may contain many interfaces. |
9 | Interface declaration for the HelloDemo component. Every ALMA component's IDL interface must inherit from ACS::ACSComponent. This ensures that all components have a unique instance name and a state visible to other components. |
11, 13 | Silly methods using CORBA types string, double, and long |
After the IDL file HelloDemo.idl has been written, a couple of Java classes must be generated from it.
The ALMA Makefile will take care of this, given the line (see jcontexmpl/src/Makefile)
IDL_FILES = HelloDemo
The generated Java classes are then automatically compiled and put into /lib/HelloDemo.jar. They belong to the package alma.demo and can be categorized as
...
Warning: don't choose the same name for IDL_FILES as for (one of the values of) JARFILES in your Makefile! Otherwise the jar files produced from the IDL and from your module's code have the same name and one gets overwritten by the other.
...
The implementation of a Java component is a Java class that must implement
The implementation of a Java component is a Java class that must implement
The implementation class may inherit from any base class (This is possible because for Java components the framework uses the CORBA tie delegation model; C++ class may inherit from any base class This is possible because for Java components the framework uses the CORBA tie delegation model; C++ components can use multiple inheritance and extend the CORBA skeleton directly, thus saving one runtime delegation step.); no such base class is required by the framework though, which saves the single inheritance option offered by Java.
For components that don't don’t need inheritance for other purposes, there is a generic base class class (alma.acs.component.ComponentImplBase)that provides standard implementations of the required methods from ComponentLifecycle and ACSComponent, just to keep the component code simpler.
In real life we would usually first create the component implementation class with just dummy implementations for all mandatory methods, e.g. using code generation features of an IDE like Eclipse, and then move on to the next steps described in sections 6 and sections 6and below. This document will ignore the iterative process and look at the final implementations right away.
The functional interface for the HelloDemo component is HelloDemoOperations, a Java interface generated by the CORBA IDL compiler.
By convention, we call the implementation class "HelloDemoImpl" “HelloDemoImpl” and create it in the package "alma“alma.demo.HelloDemoImpl"HelloDemoImpl”. It can be found under jcontexmpl/src in CVS.
01
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
/* legal info cut |
...
out */ package alma.demo.HelloDemoImpl; |
...
import java.util.logging.Logger; |
...
import org.omg.CORBA.DoubleHolder; |
...
import org.omg.CORBA.IntHolder; |
...
import alma.ACS.ComponentStates; |
...
import alma.acs.component.ComponentLifecycle; |
...
import alma.acs.container.ContainerServices; |
...
import alma.demo.HelloDemoOperations; |
...
/** Javadoc cut out |
...
*/ public class HelloDemoImpl implements ComponentLifecycle, HelloDemoOperations { private ContainerServices m_containerServices; private Logger m_logger; ///////////////////////////////////////////////////////////// |
...
// Implementation of ComponentLifecycle ///////////////////////////////////////////////////////////// |
...
public void initialize(ContainerServices containerServices) { m_containerServices = containerServices; m_logger = m_containerServices.getLogger(); |
...
m_logger.info("initialize() |
...
called..."); |
...
} public void execute() |
...
{ m_logger.info("execute() |
...
called..."); |
...
} public void cleanUp() |
...
{ m_logger.info("cleanUp() |
...
called..., |
...
nothing to clean up."); |
...
} public void aboutToAbort() |
...
{ cleanUp(); |
...
m_logger.info(" |
...
managed to abort..."); |
...
} ///////////////////////////////////////////////////////////// |
...
// Implementation of ACSComponent ///////////////////////////////////////////////////////////// |
...
public ComponentStates componentState() { return m_containerServices.getComponentStateManager().getCurrentState(); |
...
} public String name() { return m_containerServices.getComponentInstanceName(); |
...
} ///////////////////////////////////////////////////////////// |
...
// Implementation of HelloDemoOperations ///////////////////////////////////////////////////////////// |
...
public String sayHello() { m_logger.info(" |
...
sayHello called..."); |
...
return "hello"; |
...
} public String sayHelloWithParameters(String inString, DoubleHolder inoutDouble, IntHolder outInt) { m_logger.info(" |
...
sayHello called with arguments inString=" + inString + "; inoutDouble=" + inoutDouble.value + ". Will return 'hello'..."); |
...
outInt. |
...
value = |
...
(int) |
...
Math.round(Math. |
...
E * |
...
10000000); |
...
return "hello"; |
...
} } |
20 | The package declaration in accord with the "subpackage-per-component-implementation" convention |
21 | Import for logging (standard JDK logger configured by ACS) |
22-23 | Imports for CORBA Holder classes for the OUT parameters in the sayHelloWithParameters method (as defined in [9]) |
24 | Import of the ComponentStates interface, needed to access (and optionally modify) the component state |
25 | Import for the mandatory Lifecycle interface |
26 | Import for the ContainerServices interface which the container provides to the component. From this interface, the component gets everything the container can do for it on request (that is, not transparently w/o the component noticing) |
27 | Import for the HelloDemoOperations interface, which defines the functional methods that a client of our component would use. |
38 | The component implementation class implements the functional and the lifecycle interface; it does not inherit from any base class (if so, there would be even less here to look at…) |
40 | Reference to the ContainerServices object that the container will give us (see line 47) |
41 | Ref to the logger object which we'll get from the container (see line 49) |
47-51 | The initialize method (from ComponentLifecycle) is called by the container after creating an instance of our component. It provides us with the ContainerServices object. We don't use it for much besides getting a logger and storing that reference in a separate variable for easy access. |
52-54 | Implementation of the execute method (from ComponentLifecycle). This method will be called by the container after initialize() has returned. Only few components are foreseen to use both initialize and execute; here we just log a message. |
55-57 | Implementation of the cleanUp method (from ComponentLifecycle). This method will be called by the container when the component is getting dismissed by the ACS Manager, but only after the last call to any of the methods from HelloDemoOperations has returned. |
58-61 | Implementation of the aboutToAbort method (from ComponentLifecycle). This method may be called asynchronously when the container or the entire ALMA system must shut down without waiting for proper termination of all components. It is meant as a notification to the component to perform the most urgent actions before being forcefully removed at any time. |
67-69 | Implementation of the componentState() method (from ACSComponent). |
70-72 | Implementation of the name() method (from ACSComponent). The name is the instance name of our component, e.g. something we can't know at compile time. We get the name from the container, using the ContainerServices interface. |
78-81 | Implementation of the sayHello method which is declared in HelloDemoOperations. |
83-90 | Implementation of the sayHelloWithParameters method: we set the OUT parameter and leave the INOUT parameter untouched. |
Note the use of DoubleHolder and IntHolder for outgoing parameters, a concept that is not possible in Java without using these helper classes; they are therefore defined in the CORBA IDL-to-Java mapping spec. [9] |
Note that the implementation of the HelloDemo component is done with just one Java class. A real component would rather have one main implementation class that implements the component interfaces and uses other classes to perform the functional tasks.
...
...
Unlike the previous HelloDemo, the component XmlComponent uses entity objects that are transported over the network as serialized XML. We will focus on this feature and not repeat things which have already been demonstrated before.
...
...
The term “entity” refers to non-primitive,
...
non-binary
...
data
...
with
...
identity
...
such
...
as
...
scheduling
...
blocks,
...
system
...
users,
...
correlator
...
configurations
...
etc.,
...
c.f.
...
[1
...
].
...
These
...
data
...
types
...
are
...
defined
...
in
...
XML
...
schemas.
...
Their
...
instances
...
are
...
XML
...
“documents” that
...
get
...
passed
...
around
...
by
...
value
...
and
...
can
...
be
...
stored
...
in
...
the
...
ALMA
...
Archive.
...
From the XML schemas, we produce Java classes at build-time,
...
based
...
on
...
the
...
Castor
...
framework
...
[12
...
].
...
These
...
binding
...
classes
...
represent
...
the
...
hierarchical
...
data
...
structure
...
in
...
memory.
...
They
...
have
...
type-safe
...
methods
...
to
...
navigate
...
the
...
tree
...
and
...
to
...
access
...
data
...
items.
...
The
...
binding
...
classes
...
can
...
be
...
automatically
...
instantiated
...
from
...
XML
...
documents
...
that
...
correspond
...
to
...
the
...
same
...
schema,
...
and
...
can
...
serialize
...
their
...
data
...
into
...
stringified
...
XML.
...
The idea of “transparent XML entities” is to have the entity objects transported by CORBA as language-neutral XML strings. However, the Java component implementations (both client and server involved in the remote call) don’t have to worry about the serialization and parsing of the XML. The main advantage of this is that the framework ensures type safety, from the IDL/schema definitions, all the way down to the Java implementation classes of a component; it’s not possible to be surprised at runtime that the received XML differs in type or version from what the component expected. To achieve this, the implementation classes use modified component interfaces, in which Java binding classes are substituted for the structs with serialized XML. An example with detailed explanation will be given in 5.3.
A Java component that acts either as a client or as a server with respect to some other component, is completely independent in its decision whether to parse XML entity objects “by hand” or to enjoy transparent support for binding classes. The other component may be written in Java, C++, or whatever other language, and it may or may not use binding classes (If this other component is written in Java, the developer has a real choice on this; for C++ at least at the moment there is no support for XML binding classes, so the C++ XML parser (expat) that comes with ACS should be used.).
For example, a Java client that exchanges XML entity objects with a C++ server can work with Java binding classes, whereas the C++ server parses the XML using a SAX parser.
...
We define complex data types in XML schema and use these types in CORBA IDL similar to how CORBA structs would be used.
To keep this tutorial focused on component development, we only touch on the schema development issue. Rather than showing how to develop a new schema, we use the existing schemas from the module acstestentities.
For XML schemas describing ALMA entities, there are the following conventions:
...
Schema files must be put into the /idl directory of your module, or into the ICD/<yourSubsystem>/ws/idl directory if Like IDL files are meant to be used by other subsystems. Please check with ALMA software engineering.
You must add information to your module's Makefile so that the XML schemas can be compiled into Java binding classes. Let's look at how acstestentities/src/Makefile has it:
XSDBIND = acsTestEntities
tells the build process to look for a configuration file ../idl/acsTestEntities.xml which must provide information about the schema files to be compiled (see below). The resulting Java classes will then be packed into ../lib/acsTestEntities.jar.
Schema files can include or import other schema files. In our case, CommonEntity.xsd from the module ACS/define, systementities.jar, is imported. In our Makefile, the line
XSDBIND_INCLUDE = systementities
is required so that the build process can set the include path for the schema compiler.
Here's a reduced listing of the configuration file /idl/acsTestEntities.xml
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8" ?> |
...
<EntitybuilderSettings> <EntitySchema schemaName="TestObsProject.xsd" xmlNamespace="AlmaTest/ObsProject" /> |
...
<EntitySchema schemaName="TestObsProposal.xsd" xmlNamespace="AlmaTest/ObsProposal" /> |
...
<EntitySchema schemaName="TestSchedBlock.xsd" xmlNamespace="AlmaTest/SchedBlock" /> |
...
<XmlNamespace2JPackage xmlNamespace="AlmaTest/ObsProject" jPackage="alma.xmljbind.test.obsproject" /> |
...
<XmlNamespace2JPackage xmlNamespace="AlmaTest/ObsProposal" jPackage="alma.xmljbind.test.obsproposal" /> |
...
<XmlNamespace2JPackage xmlNamespace="AlmaTest/SchedBlock" jPackage="alma.xmljbind.test.schedblock" /> |
...
</ |
...
EntitybuilderSettings> |
We see that schema files are listed together with their xml namespaces (<EntitySchema>). Then the namespaces are mapped to Java packages (<XmlNamespace2JPackage>). Files and packages are separated here because several schema files can use the same xml namespace, but the Java package of the resulting classes must depend on the namespace, not the schema file.
Note that the compilation of xml schemas is specified differently in the Makefile, compared with the compilation of IDL files. IDL files are listed individually and are compiled into one jar file each, whereas schema files are only referenced indirectly through their XML configuration file, and are compiled into only one jar file per module.
The diagram below illustrates the relationships among the xml schema files, IDL files, and Makefiles from our module "acsjexmpl" and the modules "define" and "acstestentities" from where resources are used by the example module.
...
...
Using XML schema types in IDL – general idea
The diagram below shows how to use the XML schema definition of a SchedBlock in the IDL definition of a component interface.
...
Here
...
Here's a thinned-out listing. Since lines are missing, we use letter tags instead of line numbers.
A #include <xmlentity.idl>
#include <acscomponent.idl>
B #pragma prefix "alma"
C module demo
{
D typedef xmlentity::XmlEntityStruct ObsProposal;
typedef xmlentity::XmlEntityStruct SchedBlock;
typedef sequence <SchedBlock> SchedBlockSeq;
E exception XmlComponentException {};
F struct ObsProjectTree
{
ObsProposal prop;
SchedBlockSeq schedBlocks;
};
G interface XmlComponent : ACS::ACSComponent
{
H long dumbMethod(in string somevalue);
I ObsProposal createObsProposal();
J SchedBlockSeq getAllSchedBlocks();
K void xmlInOutMethod(in ObsProposal opsPropIn,
out SchedBlock schedBlockOut);
L ObsProjectTree getEntireTreeInAStruct();
M void exceptionMethod() raises (XmlComponentException);
};
};
Code Block | ||||
---|---|---|---|---|
| ||||
#include <xmlentity.idl>
#include <acscomponent.idl>
#pragma prefix "alma"
module demo
{
typedef xmlentity::XmlEntityStruct ObsProposal;
typedef xmlentity::XmlEntityStruct SchedBlock;
typedef sequence <SchedBlock> SchedBlockSeq;
exception XmlComponentException {};
struct ObsProjectTree
{
ObsProposal prop;
SchedBlockSeq schedBlocks;
};
interface XmlComponent : ACS::ACSComponent
{
long dumbMethod(in string somevalue);
ObsProposal createObsProposal();
SchedBlockSeq getAllSchedBlocks();
void xmlInOutMethod(in ObsProposal opsPropIn,
out SchedBlock schedBlockOut);
ObsProjectTree getEntireTreeInAStruct();
void exceptionMethod() raises (XmlComponentException);
};
};
|
A | xmlentity.idl comes from define/idl and declares the CORBA struct XmlEntityStruct which is used to transport serialized XML together with some meta data. It must be included whenever xml entity objects are used (see I-K). The developer does usually not have to know the details of that struct. | ||
B | The prefix pragma must come after the include statements; this restriction might be lifted in the future, but for now the TAO IFR would have a problem otherwise. | ||
C | We use the same module as for the HelloDemo component | ||
D | Typedefs for xml entity classes. The interface methods that use entity classes as parameters or return types (see H-K) must use these named typedefs like 'ObsProposal' instead of 'XmlEntityStruct'. This not only makes the interface more readable, but is also required for the automatic use of Java binding classes. | ||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="cfccb5d4-5e6c-4cef-9301-f6acc082b3e5"><ac:plain-text-body><![CDATA[ | E | Declaration of an exception. (How to use the ACS Error System [6] instead of plain CORBA exceptions may be demonstrated in a future version of this document.) | ]]></ac:plain-text-body></ac:structured-macro> |
F | A struct that contains XML entities. | ||
G | Interface declaration for the XmlComponent | ||
H | Just to have something dumb in here | ||
I | Method that returns an xml entity object (as a struct that contains the xml data as a string if the component is accessed as a plain CORBA object, see below.) | ||
J | Demonstrates the use of a sequence (~array) of xml entity objects | ||
K | Demonstrates the use of xml entity objects as an OUT parameter | ||
L | Uses the ObsProjectTree struct, with entities inside | ||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="685d4215-19d0-490c-9384-82793378ebad"><ac:plain-text-body><![CDATA[ | M | Uses an exception (again, later the mechanism described in [6] will be used.) | ]]></ac:plain-text-body></ac:structured-macro> |
...