All extensions (regardless of type) and the built-in services are referred to as RF components.
Table of Contents
Components, the Component Hierarchy, and Component Information
Lifecycle, State, and Configuration
Usage of CRT Interfaces for RF Extensions
Current API: com.sapportals.wcm.util
The configuration framework (CF) stores the configuration data for all RF components. It offers a GUI that allows administrators to change the configuration for the RF's components (see [Admin Guide] for information on how to use Knowledge Management's configuration UI).
Usually, developers only have to concern themselves with the configuration classes that define the set of parameters that an extension needs. For
example, a CmRepositoryManager.cc.xml specifies the configuration class of the RF's default repository manager implementation. Configuration
classes are built using the PDK Eclipse Plugin "Configuration Wizard".
The configurables are instances of configuration classes. For example, the configuration data for the /documents repository (stored in
documents.co.xml) is an instance of CmRepositoryMananager.cc.xml. New configurables are created with the help of the configuration
UI.
For further details on how to create configuration classes and use onfigurables, see [CF].
The retrieval of a component's configuration data is handled by the component runtime, which is described in the following section.
The component runtime (CRT) manages the start-up and shutdown of RF components. It also provides the RF components with their configuration data from the configuration framework. The components' states can be inspected using the CRT component monitor, so an administrator can find out which components were started, which could not be started, and why.
Usually, the RF extensions do not need to concern themselves with the CRT because extensions are derived from the relevant RF classes
(AbstractManager, AbstractFilterManager, AbstractRepositoryService and AbstractService; see
RF Extensions), which already implement the required CRT interfaces for starting, stopping, and configuring a component with its configuration
data.
However,, it might be helpful to know the CRT's interfaces in case you implement additional features:
Most of these interfaces are tagging interfaces, such as java.lang.Cloneable, for indicating a specific feature of the component.
All components within the CRT implement the IComponent interface.
The following things are true for each component:
class attribute of the component's configuration in the
configuration framework
crt://cm/repository_manager/documents) with the URI's protocol set to crt. The path of the URI
consists of the component keys along the component hierarchy. This URI can be used to look up a component.
Components that manage child components implement the IContainer interface. For example, the AbstractManager, which is the base class for a
repository manager, contains its event broker as a child component (see RF Extensions).
The IComponentInfo and ILifecycleInfo interfaces support the retrieval of status information that is used by the CRT
component monitor to show the current status of a component.
Components can have different lifestyles. The lifestyle defines how a component is instantiated:
IThreadSafe interface indicates that a component is created only once by the CRT. Each lookup for the component then returns the
same instance of the component, handling the component like a singleton.
IPooleable indicates a component whose instances are being pooled by the CRT.
IPooleable is combined with IReusable, which indicates that a component's instance can be reset (the CRT calls
reset()) and than reused. IPooleable or IReusable must not be combined with IThreadSafe.If a component does not implement one of these three interfaces, a new instance is created each time the component is looked up or retrieved, for example,
when a global service is retrieved using IServiceFactory.getService().
The IStartable interface indicates that the component performs
an initialization on start-up and carries out a certain amount of cleaning up at shutdown.
The initialization during start() should be used by all components (instead of doing this in the components constructor). In particular, lookup
of other components must not be carried out in the components constructor, since this can lead to indissoluble lookup sequences during start-up, causing a
CyclicDependencyException to be thrown.
IAutoStartable indicates components that are instantiated automatically during the start-up of the CRT (whereas components that are not started
automatically are not be instantiated until the first lookup). Because automatic start-up only makes sense for a singleton, IAutoStartable is also
derived from IThreadSafe.
IConfigurable indicates a component that requires configuration data. The CRT retrieves the components configuration and calls
configure().
A component implements the IReconfigurable interface in order to enable hot reload. Hot reload is a component's ability to handle
changes to its configuration without requiring a system restart. When a component implements IReconfigurable, the CRT calls
reconfigure() with the changed configuration. The component must then change its internal state
in line with the new configuration.
IReconfigurable can be used in conjunction with ISuspendable, which indicates that a component should be stopped during
reconfiguration and resumed afterwards. This is especially useful if a component is not able to process any other requests during reconfiguration. The CRT
calls suspend() before and resume() after the reconfiguration for an ISuspendable, and the component
is marked as
stopped during reconfiguration, which inhibits any further lookups for that component during the suspension.
A component that implements all available lifecycle interfaces (state and configuration) has the following methods called by the CRT:
IContextualizable.contextualize(): The component receives a CRT context object that might contain parameters from the component's container
(its parent component).
IConfigurable.configure(): The component receives its configuration data.
IStartable.start(): The component initializes and acquires the resources necessary to provide its functionality.
ISuspendable.suspend(): The component is suspended for reconfiguration.
IReconfigurable.reconfigure(): The component receives new configuration data.
ISuspendable.resume(): The component is accessible again after reconfiguration.
IStartable.stop(): The component releases the acquired resources.
Each time a component changes its state (when a lifecycle interface method is called by the CRT), the component should call the appropriate
pre…()- and post…()-methods of the ComponentStateHandler when entering or
leaving the method in order to have its state automatically updated in its ILifecycleInfo.
For example, a component's reconfigure() method might look like this:
public void reconfigure(IConfiguration config)
throws ConfigurationException {
this.stateHandler.preReconfigure();
try {
… // do something for reconfiguration here
}
catch( Exception e ) {
// handle exception and throw ConfigurationException
}
finally {
this.stateHandler.postReconfigure();
}
}
If the component depends on other components (for example, a repository service usually depends on the repository manager it is assigned to), it can
implement the IComponentEventListener interface in order to be notified whenever a component is added, removed, or changed within the CRT. The CRT
calls notify() with a ComponentEvent that holds the ID of the added, changed, or removed component.
The following table shows the CRT interfaces that are implemented by the different RF base classes (semantic object factories do not currently use the CRT):
|
|
|
|
|
|
|
|
x |
x |
x |
x |
|
|
x |
|
|
|
|
|
x |
x |
x |
x |
|
|
x |
x |
x |
x |
|
|
x |
x |
x |
x |
|
|
x |
x |
x |
x |
|
|
|
x |
|
|
|
|
x |
x |
|
x |
|
|
|
x |
|
|
For further information on the CRT, see Component Runtime.
Logs are used for reporting problems. Logging includes security auditing or database logging. The class com.sap.tc.logging.Category
can be used for logging to such a (distinct) log.
While several processes or objects might write to the same log, a com.sap.tc.logging.Location represents the "source" location of the
information logged.
Traces are used for tracing code execution - they are special logs used for support and development. A trace is the default category, and the class should be used as the tracing location within the RF.
For example:
import com.sap.tc.logging.Location;
…
private static Location trace = Location.getLocation(myClass.class);
…
trace.errorT("myMethod", "myMessage");
The example creates a location instance trace. If trace.errorT() is called, an error trace is written to the RF's trace
file.
The different methods for the several severities are:
fatalT(): Should be used for errors that cause the system to stop or prevent further action (for example, "out of memory").
errorT(): Should be used for errors that cannot be resolved automatically and when data might be lost (for example, when a backend connection
becomes unavailable).
warningT(): Should be used for error that can be recovered by the system (for example, database connection lost but recovered after a
reconnect).
infoT(): Should be used for tracing the various paths through the program's execution (usually at least one trace per relevant method and
potentially one for the if-/else-branches of relevant if statements).
debugT(): Should be used for tracing the detailed developer information required to trace a problem if the result of the execution is not as
expected.
For performance reasons, tracing should only be performed for warning, info, or debug traces if the appropriate severity is set. Moreover, since the line number is not included in the trace output automatically, it might be a good idea to include it in the first parameter.
For example (using 123 as line number):
if( trace.beInfo() ) {
trace.infoT("myMethod(123)", "my info message");
}
To trace the backlog of an Exception or Throwable, the utility class LoggingFormatter is provided:
import com.sap.wcm.util.logging.LoggingFormatter;
…
try {
…
}
catch( Exception e ) {
trace.errorT(
"myMethod",
"caught exception " + e.getMessage()
+ ":" + LoggingFormatter.extractCallstack(e)
);
}
SAP logging and tracing offers a lot of additional functions. For further details, see [Logging].
Since the RF has to support a large number of users working concurrently, performance is one of the major issues in the RF.
In order to support more users than one server might be able to handle, the RF can be distributed across several servers - this is called a clustered installation. Within a cluster, several instances of the RF run on different machines (in different VMs), but these instances use the same database (configuration, backend connections, and so on).
Each RF extension must be aware of supporting a clustered installation by implementing the relevant synchronization mechanisms.
An extension can check for the clustered installation using the following code fragment:
boolean isClustered = true;
try {
ILandscapeService landscapeService =
(ILandscapeService)ResourceFactory
.getInstance()
.getServiceFactory()
.getService(IServiceTypesConst.LANDSCAPE_SERVICE);
if( landscapeService != null ) {
isClustered = landscapeService.isClusterInstallation();
}
}
catch( ResourceException e ) {
// trace exception
}
The following three lists provide a brief overview of the packages beneath com.sapportals.wcm.util and the interfaces and classes they
provide:
The first group consists of packages that are related to the RF:
com.sapportals.wcm.util.content
The IContent interface represents the (unstructured) content of a resource as a
java.io.InputStream.com.sap.netweaver.bc.rf.common.contentcom.sapportals.wcm.util.enumAbstractEnum is the base class for all enumerations of RF constants in the current
API.com.sap.netweaver.bc.rf.util.enumcom.sapportals.wcm.util.eventscom.sap.netweaver.bc.rf.util.eventcom.sapportals.wcm.util.loggingLoggingFormatter.extractCallstack() for extracting an exception's call stack
for tracing.com.sap.netweaver.bc.rf.util.loggingcom.sapportals.wcm.util.nameIName and class Name for handling an XML (namespace, name) naming
scheme (see How to use the RF's Client API and [RFC2518]).com.sap.netweaver.bc.rf.util.namespacecom.sapportals.wcm.util.resourceResourceBundles that extend java.util.ResourceBundle for multi-language support and Descriptions that support the handling of descriptions in several languages.com.sap.netweaver.bc.rf.util.resourcecom.sapportals.wcm.util.uricom.sap.netweaver.bc.rf.commoncom.sapportals.wcm.util.uuidUUID for generating Universally Unique Identifiers (UUIDs) as specified by the Internet-Draft "A UUID URN Namespace" (see [IETF-UUID]).com.sap.netweaver.bc.rf.util.uuid
The next group of packages are those that are not related to the RF. These packages will not be incorporated into the new API. Most of these packages deal with content and string handling:
com.sapportals.wcm.util.base64Base64Encoder for encoding and Base64Decoder for decoding a stream or
string into Base64 format, used for MIME data.com.sapportals.wcm.util.htmlcom.sapportals.wcm.util.httpcom.sapportals.wcm.http.slim.com.sapportals.wcm.util.mmparsercom.sapportals.wcm.util.regexPathPatternMatcher: Matches for expressions that use an "Ant" like syntax (see [ANT]).Matcher: Matches for regular expressions that are represented as Pattern.com.sapportals.wcm.util.threadscom.sapportals.wcm.util.xml
The third group of packages are implementations of features that should only be used internally. They should not be used by application developers for the following reasons: Either they provide basic functions, making it likely that either the portal runtime or the J2EE Engine will provide the same functionality in the future, the functionality is relevant for RF extensions only, or the package is already deprecated.
com.sapportals.wcm.util.aclcom.sapportals.wcm.util.cachecom.sapportals.wcm.util.channelscom.sapportals.wcm.util.configcom.sapportals.wcm.util.controlstatuscom.sapportals.wcm.util.factoriesThreadUtils will be replaced by
the J2EE
Engine's functionality.com.sapportals.wcm.util.logcom.sap.tc.logging is now
used.com.sapportals.wcm.util.systemconfigcom.sapportals.wcm.util.usermanagement
The following list is just a brief summary of the packages beneath com.sap.netweaver.bc.rf.util.
com.sap.netweaver.bc.rf.util.contextcom.sap.netweaver.bc.rf.util.enumEnum is the base class for all enumerations with RF constants in the new API.com.sapportals.wcm.util.enumcom.sap.netweaver.bc.rf.util.eventcom.sapportals.wcm.util.eventcom.sap.netweaver.bc.rf.util.exceptioncom.sap.netweaver.bc.rf.util.flyweightcom.sap.netweaver.bc.rf.util.loggingLoggingFormatter.extractCallstack() for extracting an exception's call stack for tracing (copied from the current API), and some helper
classes to initialize, configure, and format the logging.com.sapportals.wcm.util.loggingcom.sap.netweaver.bc.rf.util.namespaceIName and class Name for handling an XML (namespace, name) naming scheme (see How to use the RF's Client API and [RFC2518], copied from the
current API).com.sapportals.wcm.util.namecom.sap.netweaver.bc.rf.util.resourceResourceBundles that extend java.util.ResourceBundle for multi-language support (copied from the current API).com.sapportals.wcm.util.resourcecom.sap.netweaver.bc.rf.util.uuidUUID for generating Universally Unique Identifiers (UUIDs) as specified by the Internet draft "A UUID URN Namespace" (see IETF-UUID, copied
from the current API).com.sapportals.wcm.util.uuid