The Target ########## The class with which programmers work most often is the **Target** class. Targets are the classes that can receive messages. To make this possible, they are registered in the **TargetRegistry** of a namespace. A target receives an ID, the target ID (short: **TID**). You can give the targets their own TIDs, but usually a random ID generated by the TargetRegistry is sufficient. Targets are bound to a thread during registration. All messages they receive during their lifetime will always be received in the same thread. Messages are never passed to the target at the same time, but are always processed one after the other. Therefore, there is no need to worry about problems of concurrency. The Structure of a target ************************* | A target is any class that implements the ``ITarget`` interface. | However, it is better to derive a class from ``CTarget``, because everything necessary is already implemented here. The only thing missing is the creation of one or more *MessageHandlers* that capture and process messages addressed to this target. A typical target looks like this:: class CTestApp extends CTarget { CTestApp() { addMessageHandler(CRecordStartTarget.ID, new IMessageHandler() { @Override public boolean handleMessage(final CEnvelope aEnvelope, final CRecord aRecord) throws Exception { aEnvelope.setResult(null); return true; } }); } } Here, a *message handler* is implemented in the constructor of the object. There is a method to implement: the ``handleMessage`` method that receives the message. This also has two arguments: * The *Envelope*, which contains the message header of the message. In particular, it contains the sender and recipient addresses. It also contains a lot of meta data which is used for sending messages.. * The **Record**, which represents the payload of the message. The message ID should be mentioned here in particular. When adding a message handler to the target (``addMessageHandler (...)``) an important argument must be specified, the message ID. The message ID is of type ``IId``, and in this case it is the *StartTarget*-ID. This message is the first message sent to a newly registered target, as a welcome greeting. It comes asynchronously, i. e. it is delivered in the thread specified when registering the target. All messages of the target are delivered in this thread to prevent problems with accessing your own data. Registering a Target ******************** Targets are registered in the target registry of a namespace:: ITarget myTarget = new CTestTarget(); getNamespace().getTargetRegistry().registerTarget(myTarget, CWellKnownTID.KERNEL); The target is given an ID, the target ID (short: **TID**). Alternatively, you can enter a **TID** upon registration:: ITarget myTarget = new CTestTarget(); IId myTID = CIdFactory.create(EIdType.STRING, "TEST1"); getNamespace().getTargetRegistry().registerTarget(myTarget, myTID); Usually, however, a random ID generated by the TargetRegistry is sufficient. If the namespace has more than one thread, you can also specify the **Queue ID** of the thread:: ITarget myTarget = new CTestTarget(); IId myTID = CIdFactory.create(EIdType.STRING, "TEST1"); getNamespace().getTargetRegistry().registerTarget(myTarget, myTID, qid); The Target Address ****************** Each target receives a unique address by registration. These addresses are used in messages as recipient and sender addresses. Read more about the structure of the address :ref:`here `. The address can be retrieved after registering the target with ``getAddress()``. It is immutable, i. e. it can be passed on without fear of being changed. Removing a Target ***************** The target can be unregistered at any time:: addMessageHandler(CRecordRequestStopApp.ID, new CMessageHandler(this, "RequestStopApp") { @Override public boolean handleMessage(final CEnvelope aEnvelope, final CRecord aRecord) throws Exception { deregisterTarget(); aEnvelope.setResult(null); return true; } }); Access To The Environment ************************* Within the target you can easily access your environment:: // Get the kernel getKernel(); // Get your own namespace getNamespace(); // Get the ID of the thread in which the target is registered getQueueId(); Convenience Methods ******************* Some of the target's methods are only available for convenience. They then call methods of the namespace or kernel:: // fetches the slot factory; sometimes required when allocating messages getSlotFactory(); // TimerManager for creating timers getTimerManager(); // sends a message send(envelope, record); // sends a message send(message); // Returns a message that was previously put on hold sendBack(envelope, record); // Returns a message that was previously put on hold sendBack(message); // sends a notification; an answer is not desired. sendNotification(envelope, record); // sends a notification; an answer is not desired. sendNotification(message); // sends a request with request for response sendRequest(envelope, record); // sends a request with request for response sendRequest(message); Debugging Tools *************** Some methods make debugging easier:: // returns the simple name of the target (without package) getCurrentName(); // returns a self-assigned name getName(); // checks whether messages received by this target are logged isVerbose(); // If messages should be logged setVerbose(boolean);