EP130 SAP Knowledge Management and Collaboration Development SAP NetWeaver Information Integration
Date Training Center Instructors Education Website
Participant Handbook Course Version: 2006 Q2 Course Duration: 3 Day(s) Material Number: 50082815
An SAP course - use it to learn, reference it for work
Copyright Copyright © 2006 SAP AG. All rights reserved. No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG. The information contained herein may be changed without prior notice. Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors.
Trademarks •
Microsoft®, WINDOWS®, NT®, EXCEL®, Word®, PowerPoint® and SQL Server® are registered trademarks of Microsoft Corporation.
•
IBM®, DB2®, OS/2®, DB2/6000®, Parallel Sysplex®, MVS/ESA®, RS/6000®, AIX®, S/390®, AS/400®, OS/390®, and OS/400® are registered trademarks of IBM Corporation.
•
ORACLE® is a registered trademark of ORACLE Corporation.
•
INFORMIX®-OnLine for SAP and INFORMIX® Dynamic ServerTM are registered trademarks of Informix Software Incorporated.
•
UNIX®, X/Open®, OSF/1®, and Motif® are registered trademarks of the Open Group.
•
Citrix®, the Citrix logo, ICA®, Program Neighborhood®, MetaFrame®, WinFrame®, VideoFrame®, MultiWin® and other Citrix product names referenced herein are trademarks of Citrix Systems, Inc.
•
HTML, DHTML, XML, XHTML are trademarks or registered trademarks of W3C®, World Wide Web Consortium, Massachusetts Institute of Technology.
•
JAVA® is a registered trademark of Sun Microsystems, Inc.
•
JAVASCRIPT® is a registered trademark of Sun Microsystems, Inc., used under license for technology invented and implemented by Netscape.
•
SAP, SAP Logo, R/2, RIVA, R/3, SAP ArchiveLink, SAP Business Workflow, WebFlow, SAP EarlyWatch, BAPI, SAPPHIRE, Management Cockpit, mySAP.com Logo and mySAP.com are trademarks or registered trademarks of SAP AG in Germany and in several other countries all over the world. All other products mentioned are trademarks or registered trademarks of their respective companies.
Disclaimer THESE MATERIALS ARE PROVIDED BY SAP ON AN "AS IS" BASIS, AND SAP EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR APPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THESE MATERIALS AND THE SERVICE, INFORMATION, TEXT, GRAPHICS, LINKS, OR ANY OTHER MATERIALS AND PRODUCTS CONTAINED HEREIN. IN NO EVENT SHALL SAP BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES OF ANY KIND WHATSOEVER, INCLUDING WITHOUT LIMITATION LOST REVENUES OR LOST PROFITS, WHICH MAY RESULT FROM THE USE OF THESE MATERIALS OR INCLUDED SOFTWARE COMPONENTS.
g2007264334
About This Handbook This handbook is intended to complement the instructor-led presentation of this course, and serve as a source of reference. It is not suitable for self-study.
Typographic Conventions American English is the standard used in this handbook. The following typographic conventions are also used. Type Style
Description
Example text
Words or characters that appear on the screen. These include field names, screen titles, pushbuttons as well as menu names, paths, and options. Also used for cross-references to other documentation both internal (in this documentation) and external (in other locations, such as SAPNet).
2006/Q2
Example text
Emphasized words or phrases in body text, titles of graphics, and tables
EXAMPLE TEXT
Names of elements in the system. These include report names, program names, transaction codes, table names, and individual key words of a programming language, when surrounded by body text, for example SELECT and INCLUDE.
Example text
Screen output. This includes file and directory names and their paths, messages, names of variables and parameters, and passages of the source text of a program.
Example text
Exact user entry. These are words and characters that you enter in the system exactly as they appear in the documentation.
Variable user entry. Pointed brackets indicate that you replace these words and characters with appropriate entries.
© 2006 SAP AG. All rights reserved.
iii
About This Handbook
EP130
Icons in Body Text The following icons are used in this handbook. Icon
Meaning For more information, tips, or background Note or further explanation of previous point Exception or caution Procedures
Indicates that the item is displayed in the instructor's presentation.
iv
© 2006 SAP AG. All rights reserved.
2006/Q2
Contents Course Overview ......................................................... vii Course Goals ...........................................................vii Course Objectives .................................................... viii
Unit 1: Overview............................................................ 1 Overview .................................................................2
Unit 2: Getting Started ...................................................11 Getting Started ........................................................ 12
Unit 3: Repository Framework Concepts .......................... 33 Repository Framework Concepts ................................... 34
Unit 4: Repository Filters .............................................. 65 Repository Filters ..................................................... 66
Unit 5: Repository Managers.......................................... 77 Repository Manager Concepts ...................................... 79 Development Tools ................................................... 88 Implementing the Repository Manager ............................ 98 Mandatory Aspects ..................................................103 Mutable Extensions.................................................. 110 Using the Security Checker......................................... 118
Unit 6: KM Services .................................................... 125 KM Services Overview ..............................................126 Reporting..............................................................134 Application Properties Service .....................................144 Publishing Pipeline...................................................149
Unit 7: Flexible UI ....................................................... 159 Architecture ...........................................................160 Components ..........................................................168 Debugging ............................................................189
Unit 8: Search and Classification ................................... 197 Using the Indexmanagement API..................................198 Integrating a Search Engine ........................................210
2006/Q2
© 2006 SAP AG. All rights reserved.
v
Contents
EP130
Enhancing the KM Search iView...................................224
Unit 9: Collaboration Room Infrastructure........................ 245 Collaboration Room Infrastructure.................................246
Unit 10: Collaboration Room ......................................... 253 Collaboration Rooms ................................................254
Unit 11: Extensions..................................................... 267 Extensions ............................................................268
Unit 12: Collaboration Services ..................................... 289 Collaboration Services..............................................290
vi
© 2006 SAP AG. All rights reserved.
2006/Q2
Course Overview With its knowledge management capabilities, the SAP NetWeaver Portal provides a central, role-specific point of entry to unstructured information from various data sources. This course covers development using the Knowledge Management and Collaboration (KMC) application programming interfaces (APIs). The basic concepts behind using the API, including KMC architecture and the associated tools, are discussed in the first lessons. After that, each of the main functional areas of KMC is covered from a development perspective, with exercises to support the lessons learned.
Target Audience This course is intended for the following audiences: •
Developers with a significant amount of Java development experience who need to understand the tools available for extending and using the KMC API from within custom applications
Course Prerequisites Required Knowledge • • • •
Strong Java development skills Development knowledge of SAP NetWeaver Application Server SAP NetWeaver Portal development experience Familiarity with NetWeaver Developer Studio or Eclipse
Recommended Knowledge •
2006/Q2
Some familiarity with the basic functionality of SAP NetWeaver Knowledge Management and Collaboration
© 2006 SAP AG. All rights reserved.
vii
Course Overview
EP130
Course Goals This course will prepare you to: • • • • • • • • • •
Explain the basics of KMC architecture Set up a development environment for development of custom KMC components Use the repository framework to store and retrieve structured and unstructured data Use repository filters to manipulate information for end users Define requirements for custom repository managers in realistic situations Write reports using the knowledge management reporting API Customize the knowledge management user interface using Flex UI Develop custom search components and integrate third-party search engines into the knowledge management search concept Use the collaboration room API for custom development tasks Develop collaboration room extensions and services
Course Objectives After completing this course, you will be able to: • • • • • • • • •
Identify which JAR files are relevant for custom development tasks Correctly use the KMC Wizards delivered as part of NetWeaver Developer Studio Use properties to store structured data Define what property, namespace and content filters are used for Develop a simple repository manager and identify requirements and estimate effort for larger repository manager development projects Define what components are available to you for customization in the Flex UI Debug Flex UI configurations Use the collaboration room API to automate room functions such as creation, deletion and invitation Develop room extensions to integrate backend systems with collaboration rooms
SAP Software Component Information The information in this course pertains to the following SAP Software Components and releases:
viii
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 1 Overview Unit Overview This unit gives a functional overview of the Knowledge Management and Collaboration capabilities of SAP NetWeaver Portal. A basic introduction to the KMC architectural stack is included.
Unit Objectives After completing this unit, you will be able to: • • •
Describe the positioning and functional purpose of Knowledge Management within SAP NetWeaver List the components of Knowledge Management in SAP NetWeaver Explain the basic architecture of Knowledge Management
Unit Contents Lesson: Overview..................................................................2
2006/Q2
© 2006 SAP AG. All rights reserved.
1
Unit 1: Overview
EP130
Lesson: Overview Lesson Overview This unit gives a functional overview of the Knowledge Management and Collaboration (KMC) capabilities of SAP NetWeaver Portal. A basic introduction to the architectural stack of KMC is included.
Lesson Objectives After completing this lesson, you will be able to: • • •
Describe the positioning and functional purpose of Knowledge Management within SAP NetWeaver List the components of Knowledge Management in SAP NetWeaver Explain the basic architecture of Knowledge Management
Business Example The concepts discussed in this lesson provide a foundation for the full set of features of Knowledge Management in the SAP NetWeaver Portal. All custom development within KM requires an understanding of these concepts.
SAP NetWeaver Knowledge Management Capabilities With its Knowledge Management capabilities, SAP NetWeaver provides a central, role-specific point of entry to unstructured information from various data sources. This unstructured information can exist in different formats, such as text documents, presentations, or HTML files. Employees in an organization can access information from different sources, such as file servers, their intranet, or the World Wide Web. A generic framework integrates these data sources and provides access to the information contained in them through the portal. The Knowledge Management capabilities support you in structuring information and making it available to the correct target audience. You can use the different functions on all content of integrated data sources, as long as the technical conditions are met. Knowledge Management comprises the following functions.
2
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Overview
Function
Description
Repository integration
Unstructured information is stored in various types of repositories, such as file servers or document management systems. You can use preconfigured repository managers to integrate repositories and make their content accessible through a central entry point in the portal. APIs allow customers and partners to develop repository managers for other storage systems. You can also store documents in one of KM’s own repositories.
Folder navigation
Portal users can navigate in the folders of all integrated repositories and access the documents they contain. Access to folders and documents is controlled using permissions. The user interface for navigating in folders can be configured flexibly and modified to suit various roles. Portal users can personalize the presentation of the user interface. Open interfaces allow you to extend the user interface by integrating your own functions into the standard system.
Search
The search function finds documents in all integrated repositories. The system displays only documents for which the current user has read permission in the results list. You can also include Web site content in your indexes by using Web crawlers. This information is then also available through the search function in your portal.
2006/Q2
© 2006 SAP AG. All rights reserved.
3
Unit 1: Overview
EP130
Taxonomies and classification
A taxonomy is a hierarchical structure of categories in which you classify documents according to content, organization, or other criteria. Documents that are stored in different repositories can be included in the same category. Taxonomies allow portal users to navigate in a uniform structure throughout an organization, even if information is stored in heterogeneous storage locations. After initial configuration, the system automatically carries out classification of new and changed documents.
Knowledge Management services
Knowledge Management services are functions that you can use on the content of all connected repositories as long as technical conditions are met. These services include subscriptions, ratings, public reviews, feedback, and personal notes. You can also import documents into KM repositories from external sources by using the content exchange service.
Document creation and publishing
Every portal user can create information in the portal, provided he or she has the necessary permissions. You can upload documents that you created using a PC application directly to a KM folder. You can also use forms to create information directly in the Web browser. The publishing process is supported by various functions, such as the approval workflow. You can assign metadata to documents and other objects to make the knowledge more usable.
4
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Overview
Collaboration
Collaboration provides a set of features that allow users to collaborate on the creation and maintenance of documents within KM. This set of features includes •
•
•
• •
virtual rooms, whose members can access shared data and services independent of their location groupware integration, which allows the integration of e-mail and scheduling services used within a corporation asynchronous collaboration, including online discussions, online management of tasks, sessions, or documents, and online entry of feedback, ratings and comments application sharing and instant messaging the ability to integrate third-party services such as WebEx
The following figure gives a more technical view of how these functional components are implemented. Note: Users access Knowledge Management functionality via the SAP NetWeaver Portal. A successful portal installation is a prerequisite to using Knowledge Management; that is, KM functionality is an extension of portal functionality.
2006/Q2
© 2006 SAP AG. All rights reserved.
5
Unit 1: Overview
EP130
Figure 1: Basic Knowledge Management Components
A set of applications built around the unstructured data stored within KM exposes functionality to the KM end user and allows them to collaborate on existing data or to create new data (documents). More basic functionality (building blocks for KM applications) is generally provided by repository or global services. Finally, the repository framework layer is responsible for managing the storage of and access to the data in question, which may be stored in a variety of back-end systems. The following architectural view of the KMC technical stack gives more detail on each of the individual units that comprise KMC.
6
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Overview
Figure 2: Architectural View of KMC
The lowest layer is the repository framework (RF) layer. It offers a framework for various types of extensions. The Knowledge Management (KM) layer uses the repository framework and adds further extensions that implement functions for document management that are visible to the user (for example, repository managers such as the Web repository manager, repository services such as the subscription repository service, and global services such as the attachment service). The next layer, built upon the KM layer, is the Collaboration layer. It contains applications that allow users to collaborate within the portal, chat, share their documents, and so on. Like the KM layer, it brings its own extensions, which implement the collaborative functions into the repository framework, as well as some extensions for the flexible UI (such as the team room renderer). An application on top of the Collaboration layer can use any of the APIs offered by the layers below, either by usage (that is, implementing an application that retrieves all the documents in a given directory) or by extending them (for example, by implementing a repository manager or a flexible UI renderer).
2006/Q2
© 2006 SAP AG. All rights reserved.
7
Unit 1: Overview
EP130
Lesson Summary You should now be able to: • Describe the positioning and functional purpose of Knowledge Management within SAP NetWeaver • List the components of Knowledge Management in SAP NetWeaver • Explain the basic architecture of Knowledge Management
8
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Unit Summary
Unit Summary You should now be able to: • Describe the positioning and functional purpose of Knowledge Management within SAP NetWeaver • List the components of Knowledge Management in SAP NetWeaver • Explain the basic architecture of Knowledge Management
2006/Q2
© 2006 SAP AG. All rights reserved.
9
Unit Summary
10
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 2 Getting Started Unit Overview This unit covers the basics of setting up your development environment. You will need this information if you wish to develop your own custom KMC component or application.
Unit Objectives After completing this unit, you will be able to: • • • • •
Explain the basics of the KMC framework and development environment Set up a KMC development environment for yourself Explain the relationship between portal and KMC projects Create a simple KMC component Deploy KMC components
Unit Contents Lesson: Getting Started......................................................... 12 Procedure: Example: Creating a KM Namespace Filter ............... 20 Exercise 1: KMC Project Setup............................................ 27
2006/Q2
© 2006 SAP AG. All rights reserved.
11
Unit 2: Getting Started
EP130
Lesson: Getting Started Lesson Overview In this lesson, we will discuss setting up a development environment for development using the KMC framework.
Lesson Objectives After completing this lesson, you will be able to: • • • • •
Explain the basics of the KMC framework and development environment Set up a KMC development environment for yourself Explain the relationship between portal and KMC projects Create a simple KMC component Deploy KMC components
Business Example Your company has asked you to enhance the behavior of the Knowledge Management features of NetWeaver Portal by allowing corporate end users to only see documents and folders that are assigned to their business unit. You have decided that the best way to implement these requirements is by using a combination of document metadata and namespace filters, which requires custom development in Java. In order to complete these development activities, you need to set up a fully functional development environment.
Software Installation and Basic Setup Custom development of features within KMC will often require Java development. SAP NetWeaver Developer Studio is the development environment supplied by SAP for the purpose of developing custom Java components. NetWeaver Developer Studio is based on the open-source integrated development environment (IDE) Eclipse, and consists of a basic Eclipse installation plus a set of plug-ins or extensions delivered by SAP. These plug-ins support development tasks that are specific to SAP NetWeaver, including a set of plugins for NetWeaver Portal and KMC development, which will be discussed here.
12
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
Software Requirements •
•
Install a local Java Development Kit (JDK). Version 1.4.2 is recommended and available from http://java.sun.com/j2se/1.4.2/download.html. Check the Developer Studio Installation Guide (see below) to ensure you install the correct version, as this may change depending on your target platform version. Install a local SAP NetWeaver Developer Studio –
•
You can find this at the SAP Service Marketplace Software Distribution Center: http://service.sap.com/swdc. From the Software Distribution Center home page, select Search for all Categories on the left-hand side, then search for “developer studio”. Choose the appropriate version from the result set. – The installation guide is available under http://service.sap.com/instguidesNW04 → Installation → Installation Guide → SAP NetWeaverDeveloper Studio. You will need a remote or local SAP Enterprise Portal with KMC.
Basic Setup Once you have installed SAP NetWeaver Developer Studio, you will need to set it up for KMC development. The first step is to activate the SAP Enterprise Portal perspective in Developer Studio. Do this by clicking on the icon labeled “EP” in the perspective toolbar. If this is not accessible, you can also choose Open Perspective from the Window menu and then pick the Enterprise Portal option from the list of perspectives, as shown in the screenshot below.
Figure 3: Activate the SAP Enterprise Portal Perspective
2006/Q2
© 2006 SAP AG. All rights reserved.
13
Unit 2: Getting Started
EP130
Next, make sure that the appropriate EP and KM icons are visible in the toolbar.
Figure 4: Customize the Toolbar
The buttons in the EP plug-ins menu are used to create a basic SAP NetWeaver Portal project. Creating such a project is a prerequisite for KMC development; the KMC-specific plug-ins require an existing portal project to operate. The buttons on the KM plug-ins toolbar are used to create the actual KMC components. Once the Enterprise Portal perspective is set up correctly, the final step is to search for and copy the KMC development Java archives (JARs) to the local development environment. Caution: Make sure that you always take the relevant library JAR files from your NetWeaver Portal installation and not from your local SAP NetWeaver Developer Studio installation. Also be sure that the JAR files that you compile against in Developer Studio correspond to the server version (for example, SAP NetWeaver 2004, Support Package 19 or SAP NetWeaver 2004s, Support Package 10) that you are developing for. You can find the JAR files by searching for the following file patterns in your portal installation: • • •
14
km*_api.jar (KM application JARs) coll*_api.jar (collaboration/room extension JARs) bc*_api.jar (repository framework JARs)
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
Search for the given patterns under :\usr\sap\\JCXX\j2ee\cluster\server0\apps\sap.com\irj\servlet_jsp\irj\root\WEB-INF\portal\portalapps on a portal installation. Note: This is a Windows path. The path on a UNIX installation will be structured in the same way. Copy these JARs to a single directory on your local PC, even if you are using a local NetWeaver Portal installation.
Portal Project and KMC Component Structures The portal plug-ins are used to create an empty portal application project with: • • •
Source development folders for API and core coding A file system structure for PAR file creation A deployment descriptor file (portalapp.xml)
The KMC plug-ins work on top of the structure of a portal application project. They: • • •
Create source code skeletons for KM components Create configuration entries (XML files) for the configuration framework Create wrapper classes for registration of the developed component with the CrtClassLoaderRegistry. The CrtClassLoaderRegistry is the internal component responsible for registering new components with the internal mechanism for loading classes in order to make them available at runtime.
There are a number of KM components that are supported by NetWeaver Developer Studio KM plug-ins. The KM plug-ins will help you create: • • • • •
2006/Q2
Global services Repository services Filters Scheduler tasks Repository managers
© 2006 SAP AG. All rights reserved.
15
Unit 2: Getting Started
EP130
The basic steps required to create any of these KM components are: 1. 2. 3. 4. 5.
Create a new portal application project. Create a new portal application object (KM component). Select the portal application project in which you want to create the KM component . Choose RF Component Wizard to generate a KM component. Specify technical data:
6. 7.
• KM component ID • Java package name • Options used by KM component (optional) Finalize project. Integrate the (relevant) KM JAR files.
Portal Applications • •
•
• •
Portal applications are bundles of portal components and portal services. Portal applications are packaged as PAR (Portal Application ARchive) files – the format accepted by the Portal Runtime for deployment of portal applications. A PAR file is an archive file/standard JAR file (ZIP format) containing a portal application with an XML-based portal application deployment descriptor (DD) called portalapp.xml. A deployment descriptor describes the portal application itself and provides information required at runtime. Portal applications contain two types of resources: –
Web resources • Accessible via HTTP(s) requests to a Web server • All files are not under PORTAL-INF (WEB-INF)
–
Non-Web resources • Not accessible via an HTTP(s) request • All files under PORTAL-INF (WEB-INF)
•
•
16
A Portal application can contain: – Several portal components and several portal services – Only 1-n portal components – Only 1-n portal services Each portal Component can be accessed by .
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
Create a new Portal Application Project by either choosing File → New → Other → Portal Application → Create a Portal Application Project or by using the button available on the toolbar (see figure below).
Figure 5: Creating a New Portal Application Project
Figure 6: Enter Project Name
2006/Q2
© 2006 SAP AG. All rights reserved.
17
Unit 2: Getting Started
EP130
Figure 7: Creating a New Portal Application Project (3)
Creating a KMC Component At this point, you have created a portal application project. The next step is to use the wizard to create the basic structure for the type of component that you will be developing. There are several ways to create a KMC project: 1. 2.
From the Developer Studio toolbar. From the context menu of the selected project:
3.
• Right-click on a Developer Studio project. • Select the corresponding wizard. From within the portal application plug-in: • • • • • •
4.
Choose File → New → Other... Select the plug-in portal application. Select Create a new Portal Application Object and then choose Next. Select the portal project Select RF Component Wizard… and then choose Next. Select one of the wizards listed on the left-hand side and then choose Next. Within the repository framework plug-in: • • •
18
Choose New → File → Other.... Select the Repository Framework… plug-in. Select one of the wizards listed on the left-hand side and then choose Next.
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
Referencing KM Libraries You should now add the JARs to the build path of your portal application project. Choose Project → Properties → Java Build Path → Libraries → Add External Jars and then select the JARs that you need to develop your component. You should include only the subset of JARs that you actually need for your project (and not all JARs) to avoid unnecessary overhead. Keep in mind that you may need to revisit this step to either add or remove libraries as you develop your KMC component.
2006/Q2
© 2006 SAP AG. All rights reserved.
19
Unit 2: Getting Started
EP130
Example: Creating a KM Namespace Filter 1.
Create a portal application project using the toolbar button on the “EP Plugins” toolbar. Give your project a name. In this example, we will use the name “MyFirstNamespaceFilter”.
Figure 8: Toolbar
2.
Create a portal application object using the portal application object button on the same toolbar. It's next to the portal application project button. When prompted, select your project (“MyFirstNamespaceFilter”) and select “Next”.
3.
Select “RF Component Wizard”. Hit Next.
4.
Select “Repository Filter Wizard”. Hit Next.
5.
Fill in the information required to create the filter. • • • •
•
•
Config Framework Version: NW04 Uncheck “Generate project classpath with BC libraries from plugin” Class Name: this is the name of the Java class that will be generated. In our example, we will use “MyFirstNamespaceFilter”. Package: this is the name of the Java package that will be generated. The class will reside in this package. As an example, we will use “com.mycompany.kmc.filters”. Name: you may leave this blank, or you may choose a name for your filter. If you leave it blank, the class name is used as the name of the filter. This is the name that will be shown to administrators in the KM Configuration UI. Types: we are developing a namespace filter, so pick “Namespace” here
6.
Hit “Finish”
7.
Examine the code that was generated in your project, which now contains the skeleton code for the namespace filter, the classes used to register the deployable component with the portal runtime, and the configuration information for the namespace filter.
Details and Inner Workings of the Project Structure Registering PARs with the CrtClassLoader Registry KMC plug-ins generate a set of classes that are responsible for registering the deployable unit (PAR) with the KMC runtime. These classes implement a portal service. Since there are a variety KMC components that can be deployed, and
20
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
many of them do not require direct user interaction to run (unlike a simple portal iView), this registration process is required to allow the components to function properly. Each deployable unit has a unique key associated with it that identifies the PAR deployable unit to the KMC runtime. To avoid conflicts, modifying this key and making it unique should always be the first step in developing a KMC component . The source code below shows the contents of the class com.sap.netweaver.rf.wrapper.IRFServiceWrapper after running a KMC wizard. The value of the variable KEY is the key that identifies the deployable unit, and must be set to a unique value. The naming convention for this string is to use “.”, where “” is the PAR file name. This is a recommended naming convention, but is not required for KMC component development. You may use any value you wish, as long as it is unique to your deployable unit.
KEY Variable for Deployment package com.sap.netweaver.rf.wrapper; import com.sapportals.portal.prt.service.IService;
public interface IRFServiceWrapper extends IService { public static final String KEY = "/* To be inserted */"; }
Caution: A common mistake is to leave the value of the KEY variable unmodified. This can lead to runtime errors if other components are developed and deployed with an unmodified key. When a PAR containing a KMC component is deployed, it replaces any KMC deployable unit already on the server with the same key value. Registration of the deployable unit is handled by the second generated class in the same package, RFServiceWrapper, which implements the interface shown above. This class contains a call to CrtClassLoaderRegistry.addClassLoader(), which registers the PAR using the key value.
Registration of Classloader with CrtClassLoaderRegistry public class RFServiceWrapper implements IRFServiceWrapper { public void init( IServiceContext serviceContext ) {
2006/Q2
© 2006 SAP AG. All rights reserved.
21
Unit 2: Getting Started
EP130
mm_serviceContext = serviceContext; CrtClassLoaderRegistry.addClassLoader( this.getKey(), this.getClass().getClassLoader() ); } }
This code is mandatory for each deployable unit (PAR file). The call to CrtClassLoaderRegistry.addClassLoader() is triggered during either deployment or portal startup because it is in a class registered as a portal service. This registration is in the portalapp.xml file in the dist/PORTAL-INF directory. The following diagram shows the basic entries in the portalapp.xml file that are relevant to KMC development. These entries are all generated after use of the wizards. The SharingReference entry allows the developed portal application to use the portal applications deployed on your portal installation that contain KMC functionality. The services block of XML is responsible for triggering the registration of your deployable unit with the runtime.
Figure 9: Portal Service Configuration: Create / check
Configuration Framework Every KM component implementation needs to be registered as a configurable object in the configuration framework. This allows the repository framework to access the configuration for the KM component (for example, a repository filter) and pass it to the implementation. The KMC wizards output the basic file and folder structure required to handle this registration in the src.config folder.
22
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
The configuration information is split into two sets: 1.
2.
The meta information, or “class definition” describes the property structure to which every instance of the newly developed component will adhere. This is found in the src.config/install/meta/expanded/cm/ folder after the KMC wizard has been run. The files in this folder have the extension .cc.xml. Data or instance information gives concrete values to the properties described in the meta information. Instance information is found in the src.config/install/data/cm/ folder. The files in this folder have the extension .co.xml.
For example, after using the KMC Wizard to create the skeleton for a namespace filter, a class definition for the filter would be located under src.config/install/meta/expanded/cm/repository_filters/com.test.MyNamespaceFilter.cc.xml (this corresponds to a filter created with a name “MyNamespaceFilter” and in a package “com.test”. In addition to this class definition, the KMC Wizard will create an instance definition under src.config/install/data/cm/repository_filters/com.test.MyNamespaceFilter.co.xml. The difference between these two sets of files is much like the difference between a class and an instance of a class in Java. The class definition for a Java class describes the member variables of that class. An instance of a Java class, or object, assigns specific values to those variables. Just as in Java, it is possible to have multiple instances, but not multiple class definitions. The configuration information can be extended by the developer to allow custom configuration of components. Within the class definition, you can specify additional properties using the attribute tag. The configuration information can be changed after deployment using the standard KM configuration iView from within the portal. All deployable units are configured here, but the exact location within the menu tree depends on the type of component being developed. Finally, the configuration information can be accessed from within the developed component at runtime. The method of access will vary slightly depending on what type of KM component is being developed. In our example, the namespace filter is accessed in the startUpImpl() method of the namespace filter manager class.
2006/Q2
© 2006 SAP AG. All rights reserved.
23
Unit 2: Getting Started
EP130
Offline Deployment and Deployment Using PAR Export Wizards There are two methods to deploy KMC components you have developed to a NetWeaver Portal installation: 1.
2.
Deploy by placing a generated PAR file into the portal's file system and restart the portal. This is the safest method of deployment. Generated PAR files can be placed under apps\sap.com\irj\servlet_jsp\irj\root\WEB-INF\deployment\pcd on a node's file system. Deploy to a running portal using either the deployment iView in the portal or the PAR Export Wizard in SAP NetWeaver Developer Studio. This is known as “hot deployment” and has associated risks (see SAP Note 894884). Specifically, repeated hot deployments can lead to an OutOfMemoryError on the server. Hot deployments can be done only in development environments (not production environments) at the customer's own risk.
To generate a PAR file needed for either deployment method, use the PAR Export Wizard available from the Portal toolbar in SAP NetWeaver Developer Studio. The toolbar also includes buttons to create a new portal application or portal application object.
Figure 10: Generating a PAR File for Export
After pressing the button and choosing the project for which you want to generate a PAR file, an option screen appears that shows where the PAR file will be output. This screen also allows the deployment of the PAR file to a running portal if the Deploy PAR checkbox is selected.
24
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
If you have not yet set up a portal to which to deploy, you can do so on this screen after selecting the Deploy PAR checkbox by pressing the Configure server settings... button and filling out the information for your portal instance. You can also perform this configuration by choosing Window → Preferences → SAP Enterprise Portal.
Figure 11: Setting Up a Portal Entry for Deployment
Note that for logon, you specify a portal user who has authorization for deployment of PAR files. This can, for example, be a user with the system administrator role. Later, when you deploy files to the portal, you need to enter the password for this user.
2006/Q2
© 2006 SAP AG. All rights reserved.
25
Unit 2: Getting Started
26
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
Exercise 1: KMC Project Setup Exercise Objectives After completing this exercise, you will be able to: • Create new KMC project in SAP NetWeaver Developer Studio • Identify required libraries
Business Example These basic steps are necessary every time you need to implement KM applications or logic based on the KM API.
Task 1: Opening the Enterprise Portal perspective in SAP NetWeaver Developer Studio 1.
Start the SAP NetWeaver Developer Studio.
2.
Open the Enterprise Portal perspective.
Task 2: Create a portal application project 1.
Create a portal application project.
2.
Name the portal application project.
Task 3: Add a NamespaceFilter object 1.
Add a NamespaceFilter object.
Task 4: Check project consistency 1.
2006/Q2
Check project consistency.
© 2006 SAP AG. All rights reserved.
27
Unit 2: Getting Started
EP130
Solution 1: KMC Project Setup Task 1: Opening the Enterprise Portal perspective in SAP NetWeaver Developer Studio 1.
Start the SAP NetWeaver Developer Studio. a)
2.
Click the link on your desktop.
Open the Enterprise Portal perspective. a)
Choose Window → Open Perspective → Enterprise Portal.
Task 2: Create a portal application project 1.
Create a portal application project. a)
2.
Choose File → New → Create new Portal Application Project.
Name the portal application project. a)
Enter CollectionNamespaceFilter as Project name and press the Finish button.
Task 3: Add a NamespaceFilter object 1.
Add a NamespaceFilter object. a)
Choose File → New → Create new Portal Application Object.
b)
Select the newly created portal application project, “CollectionNamespaceFilter.”
c)
Choose the RF Component wizard.
d)
Choose the Repository Filter wizard.
e)
Deselect the option Generate project classpath with BC libraries from plugin.
f)
Enter CollectionNamespaceFilter as Class name.
g)
Enter com.sap.training as Package name.
h)
Choose Namespace in the Types selection box and press the Finish button.
Continued on next page
28
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Getting Started
Task 4: Check project consistency 1.
2006/Q2
Check project consistency. a)
Browse to the src.api folder and check if a class IRFServiceWrapper exists.
b)
Change the static final key variable to “com.sap.training.CollectionNamespaceFilter.”
c)
Goto the portalapps.xml file and set the Startup property in the service config area to .
d)
Save the project.
© 2006 SAP AG. All rights reserved.
29
Unit 2: Getting Started
EP130
Lesson Summary You should now be able to: • Explain the basics of the KMC framework and development environment • Set up a KMC development environment for yourself • Explain the relationship between portal and KMC projects • Create a simple KMC component • Deploy KMC components
30
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Unit Summary
Unit Summary You should now be able to: • Explain the basics of the KMC framework and development environment • Set up a KMC development environment for yourself • Explain the relationship between portal and KMC projects • Create a simple KMC component • Deploy KMC components
2006/Q2
© 2006 SAP AG. All rights reserved.
31
Unit Summary
32
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 3 Repository Framework Concepts Unit Overview This unit discusses the basics of the repository framework. This layer is a central component of the KMC stack of functionality.
Unit Objectives After completing this unit, you will be able to: • • •
Explain the role and function of the repository framework layer within the KM architecture stack List the components that make up the repository framework layer Describe how information is structured in KM
Unit Contents Lesson: Repository Framework Concepts.................................... 34 Exercise 2: Using the Repository Framework API from Within an iView........................................................................... 55
2006/Q2
© 2006 SAP AG. All rights reserved.
33
Unit 3: Repository Framework Concepts
EP130
Lesson: Repository Framework Concepts Lesson Overview This unit discusses the repository framework, a central component of the KMC stack of functionality. It outlines the relationship of the repository framework to the other components of KMC. The individual components that make up the repository framework layer are covered in detail, as well as the basics of storing and retrieving content and metadata using the API. We will also discuss the eventing mechanism. Finally, advanced concepts such as locking and ID mapping are briefly outlined.
Lesson Objectives After completing this lesson, you will be able to: • • •
Explain the role and function of the repository framework layer within the KM architecture stack List the components that make up the repository framework layer Describe how information is structured in KM
Business Example Your system administrator has asked you to develop a simple iView that shows all properties (metadata) for a given document (resource) in KM in order to help debug the system. You use the repository framework to access this information in KM and then display it in the iView.
The Repository Framework Layer The repository framework is an extensible framework that offers unified access to objects provided by various information sources.
34
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Figure 12: Positioning of the Repository Framework Layer
An information source (or repository) can be a store (for example, a document management system or a file system) that typically stores unstructured data such as text or graphics. It might also be a back-end system (for example, a database or an ERP system) that typically contains structured data, such as data records or business objects. A repository is connected to the repository framework using its repository manager. The repository manager is responsible for converting the repository’s internal representation of the stored information into the unified aspects of the repository framework, and vice versa. Unified access eases application development, because application developers do not need to pay attention to the specifics of interacting with different information sources. For example, a workflow application based on the repository framework will instantly be extended to any other kind of document or business objects as soon as the repository framework is extended with a new repository – without requiring changes to any code in the workflow application. In turn, objects from information sources benefit from the applications on top of the repository framework. For example, when the repository framework is extended with a new repository, all objects exposed to this new repository can instantly be searched using the generic search engine – without the need to re-implement such functionality in the repository itself.
2006/Q2
© 2006 SAP AG. All rights reserved.
35
Unit 3: Repository Framework Concepts
EP130
Figure 13: Review of KM Architectural Layers
In the figure above, the lowest layer is the repository framework layer. It offers an extensible framework for various types of extensions. The Knowledge Management (KM) layer uses the repository framework and adds further extensions that implement the functions for document management that are visible to the user (for example, repository managers such as the Web repository manager, repository services such as the subscription repository service, and global services such as the attachment service). The next layer, built upon the KM layer, is the collaboration layer. It offers applications that allow users to collaborate within the portal, chat, share their documents, and so on. Like the KM layer, it brings its own extensions that implement collaborative functions into the repository framework, as well as some extensions for the flexible UI (such as the team room renderer). An application on top of these layers can use any of the APIs offered by these layers, by usage (that is, implementing an application that retrieves all the documents in a given directory) or by extending them (for example, by implementing a repository manager or an flexible UI renderer).
36
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Figure 14: Inside the Repository Framework
2006/Q2
© 2006 SAP AG. All rights reserved.
37
Unit 3: Repository Framework Concepts
EP130
The following types of repository framework extensions are distinguished: •
Repository managers handle the mapping between repository framework objects and the back-end system (information source). For example, the File System repository manager maps files and directories of the file system to resources and collections.
•
Repository filters allow the manipulation of repository framework objects as they are passed through the repository framework. For example, the HTML Stylesheet filter applies a CSS to resources with content type text/html.
•
Repository services offer additional unified aspects for the resources of a specific repository. For example the Application Properties service offers additional properties to be stored along with a resource, which an application might use to save additional data for that resource, such as a timestamp that indicates the application-specific lifetime of a resource.
•
Global services offer additional unified aspects for all repository framework resources. For example, the Relation service allows storage and retrieval of relations between resources, which an application might use to save interdependency information about resources, such as “document X is attached to document Y.”
•
Semantic object: represent some special aspects of the resource objects. For example, a resource might be converted into the semantic object “Team Room.”
38
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Figure 15: Layers That Build on the Repository Framework
KM software components and their interfaces can be grouped into two main layers: • •
The repository framework layer The Knowledge Management application layer
The framework layer provides the fundamental components that enable the integration of repositories, the basic handling of resources, and the construction of applications on top of the framework. In contrast, the application layer provides ready-made components that run on top of the framework. These components are called services and offer useful modules of functionality that can be re-used and modified for different environments. The functionality is exposed by the API, which can be used to implement new variants of the services or to integrate the existing implementation into other applications. The application layer also includes a flexible UI feature. This allows navigation through repositories to be customized. A user accesses items in a repository with a Browse iView.
2006/Q2
© 2006 SAP AG. All rights reserved.
39
Unit 3: Repository Framework Concepts
EP130
Figure 16: Repository Framework Concepts
The Collaboration Room 6.0 framework combines different functional aspects of both the portal and the KM platform into one consistent application. The Rooms API provides an abstraction from this heterogeneous system landscape and therefore offers scenario-oriented access to the functionality of the rooms. Three main parts of SAP Enterprise Portal and KM framework are used to store rooms and room-related information: • • •
40
Portal Content Directory (PCD) User management Repository framework
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Figure 17: Unified and Semantic Views
The characteristics of the repository framework’s unified objects (called resources and collections) are as follows: •
•
• • • •
2006/Q2
Each resource represents a unified data object within the repository framework, such as a file or directory in the file system or a WebDAV resource). A collection is a special kind of resource that contains other resources (much like a directory contains files or subdirectories in the file system, or like a WebDAV collection resource). Each resource has a unique, hierarchical name (like a file has a file name or like a WebDAV resource has a URI). Each resource may contain unstructured data (content), even though a collection does not usually have content. Each resource may contain structured data (attributes or properties). Each resource may be converted to or from a business object (also called a semantic object in the repository framework).
© 2006 SAP AG. All rights reserved.
41
Unit 3: Repository Framework Concepts
EP130
Figure 18: Resource Identifiers (RIDs)
A Resource Identifier (RID) is something like a hybrid between a relative Unified Resource Identifier (URI), – but without a net_path component – and a file name – but with an URI-like query component. A more formal definition of the RID syntax is: ::= empty | [ ‘?’ ] ::= [ ‘/’ ] ::= any text, not containing ‘/’ and ‘?’ ::= empty | [ ‘&’ ] ::= [ ‘=’ ] ::= any text, not containing ‘=’ and ‘&’ ::= any text, not containing ‘&’
The root resource (denoted by ‘/’) is reserved for the repository framework itself.
42
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Basic Actions using the Repository Framework API
Figure 19: Class Dependencies in the Repository Framework
IResource represents an repository framework object (resource). ICollection represents a collection and extends IResource. IResource itself extends ITypeCast, which represent a semantic object. The following source code shows how to use the main entry point to the repository framework (IResourceFactory) to retrieve a resource.
// user retrieval not shown, since this is dependent // on context of code IUser user = …;
IResourceFactory factory = ResourceFactory.getInstance(); RID rid = RID.getRID(“/etc”); IResourceContext context = new ResourceContext(user);
IResource resource = factory.getResource(rid, context);
2006/Q2
© 2006 SAP AG. All rights reserved.
43
Unit 3: Repository Framework Concepts
EP130
An instance of IResourceFactory can be retrieved by calling the static method ResourceFactory.getInstance(). The class …util.uri.RID represents an RID. This class offers the static factory method RID.getRID(), which is used to create a RID from a string. IResourceContext represents a resource context. ResourceContext is the repository framework’s implementation of this interface. To create a ResourceContext, a user must be supplied. A resource’s RID and resource context can be retrieved with getRID() and getContext(). A collection is retrieved in the same way. The returned object should be checked to ensure that it is a collection. Following a successful check, it can then simply be typecasted to ICollection. A collection’s children are retrieved with its getChildren() method.
if(resource.isCollection()) { ICollection collection = (ICollection)resource; IResourceList children = collection.getChildren(); }
Figure 20: Basic Actions in the Repository Framework
Resources can only be created in a collection. Resources can be copied to another RID, which duplicates the data of the resource copied in a new resource for the given RID.
44
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Resources can be deleted. Once a resource is deleted, it is no longer accessible. Renaming a resource only changes its name. It does not change the parent-child relationship; the resource remains in its parent collection. Moving a resource changes the RID of this resource. Moving is like copying the resource to a new resource RID and then deleting the resource with the old RID. A link is just a reference to a real resource: the link target. The following example retrieves the /documents folder and creates an empty resource (without properties or content) called /documents/file.
IResourceFactory factory =
ResourceFactory.getInstance();
IResourceContext context = new ResourceContext(user); ICollection parent = (ICollection)factory.getResource(“/documents”, context); IResource resource = parent.createResource(“file”, null, null);
The following example retrieves the /documents folder and creates an empty collection, /documents/folder, without properties.
IResourceFactory factory =
ResourceFactory.getInstance();
IResourceContext context = new ResourceContext(user);
ICollection parent = (ICollection)factory.getResource(“/documents”, context); ICollection collection =
parent.createCollection(“folder”, null);
The operations for copying, deleting, moving and renaming are available through the IResource interface:
IResource copied = resource.copy(“/documents/copy”, null); IResource moved = copied.move(“/documents/folder”, null);
IResource renamed = moved.rename(“renamed_copy”); renamed.delete();
2006/Q2
© 2006 SAP AG. All rights reserved.
45
Unit 3: Repository Framework Concepts
•
• • •
EP130
copy() expects the destination RID and an optional ICopyParameter. This parameter is a descriptor, which might supply additional parameters (for example, if children should also be copied recursively). delete() deletes the resource, collection, or link itself. When a collection is deleted, all its children will also be deleted. move() expects the same parameters as the copy method. rename() just expects the new name of the resource.
Links are not represented by a dedicated class; the relevant operations are assigned to the IResource interface. Internal and external link types are identified by appropriate enum.LinkType values. Depending on the LinkType, the link’s target is either returned as an URL (for external links) or as an IResource (for internal links). Since methods, which differ only in their return value, may not be overloaded, the appropriate getTargetURL() or getTargetResource() method has to be called.
if(LinkType.EXTERNAL.equals(resource.getLinkType())){ // external link to an URL URL target = resource.getTargetURL(); } else if (LinkType.INTERNAL.equals(resource.getLinkType())) { // internal link to another resource IResource target = resource.getTargetResource(); } else { // not a link }
Setting the content is either done during creation of a resource or by using IResource.updateContent(). IResource.getContent() is used to retrieve the content of a resource .
String out = new String(“my content”);
ByteArrayInputStream data = new ByteArrayInputStream(out.getBytes()); IContent newContent = new Content(data, “text/plain”, data.available()); resource.updateContent(newContent);
// simple content retrieval
46
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
IContent theContent = resource.getContent();
Figure 21: Class Diagram for Metadata Handling
A property’s read-only operations are assigned to IProperty. The corresponding implementation is Property. The write operations are assigned to IMutableProperty, with MutableProperty as corresponding implementation. The name of a property is modeled as IPropertyName, with PropertyName as implementing class. IPropertyName is derived from …util.name.IName, which holds the tuple (two-pair) of (namespace, name). The property’s attributes are modelled as java.util.Properties.
String namespace = “http://sample.com/xmlns/sample”; String name = “property”; IPropertyName propertyName = new PropertyName(namespace, name); IProperty property =
resource.getProperty(propertyName);
if( property != null ) { // property exists String value = property.getValueAsString(); }
2006/Q2
© 2006 SAP AG. All rights reserved.
47
Unit 3: Repository Framework Concepts
EP130
The Eventing Mechanism
Figure 22: Synchronous Eventing in the Repository Framework
The event receiver is called back while a operation is performed for a resource. The event that indicates the operation is sent as a pre- and a post-event. The pre-event is sent before the operation is performed, and the post-event is sent when the operation has been performed successfully. Synchronous event receivers must take performance into account, since the repository blocks any other operation on the resource while the operation (and the processing of the events) is in progress.
Figure 23: Asynchronous Eventing in the Repository Framework
The event receiver is called back from a separate thread that buffers events in an event queue.
48
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
The event receiver might perform lengthy operations when receiving an event for an operation, because the repository is able to finish processing the operation without waiting for the event receiver to return from the call. On the other hand, the event receiver cannot rely on pre-events, because they might be received after the operation has been performed. •
Retrieval
•
– get, getChildren Content and Property
•
– set, setProperty, getProperty, deleteProperty Namespace
•
– createChild, createCollection, createLink, delete, move, copy, rename Locking
•
– lock, unlock Versioning –
checkin, checkout, undocheckout, enableVersioning
Events are sent as pre-events before an operation starts, and as post-events after the operation has been completed. If the operation fails, no post-event is sent. To identify events that belong together (for example, pairs of pre- and post-events), events can provide a correlation ID. As well as its type, which defines the operation causing the event, the event contains the resource to which the operation was applied.
IResourceEventSender sender = … IResourceEventBroker broker =
resource.getRepositoryManager().getEventBroker();
broker.register(sender); broker.send(ResourceEvent.GET ,sender);
An instance of the EventSender class must be registered with a repository's event broker.
public class MyEventReceiver implements IResourceEventReceiver { public MyEventReceiver() { IResourceEventBroker broker = resource.getRepositoryManager().getEventBroker(); broker.register(this, IResourceEvent.RENAME_EVENT , IEventBroker.PRIO_MIN, true); }
2006/Q2
© 2006 SAP AG. All rights reserved.
49
Unit 3: Repository Framework Concepts
EP130
public void received(IEvent event) { if( event instanceof IResourceEvent ) { IResourceEvent resourceEvent = (IResourceEvent)event; IResource resource = resourceEvent.getResource(); ... } }
An application must implement the manager.IResourceEventReceiver interface in order to receive events.
Advanced Concepts TODO: ...
Security To prevent sensitive information being shown to unauthorized users, some kind of security mechanism has to be made available. The concrete implementation of a security mechanism is provided by the repository manager and implements the com.sapportals.wcm.repository.manager.ISecurityManager interface. The security manager is therefore accessed via the repository manager's interface, IRepositoryManager, which in turn can be retrieved from the resource object. The following code sample illustrates the basic retrieval of the security manager as well as a check for read access to a resource.
// rid and context objects have been previously defined IResource theResource = ResourceFactory.getInstance().getResource( rid, context); IRepositoryManager theRM = IReptheResource.getRepositoryManager(); ISecurityManager
theSM = theRM.getSecurityManager();
// this checks to see if the user 'userA' has permission to read the content of the // resource 'theResource' theSM.isAllowed( theResource, userA, theSM.getPermission(IPermission.PERMISSION_READ_CONTENT));
Other permissions that can be checked (and assigned to users) are: resource creation and deletion, directory listing, content, and property retrieval, and content and property write permissions.
50
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Beyond these basic permission operations, retrieval and manipulation of ACLs of a resource are possible using the IAclSecurityManager interface, which provides access to the IResourceAclManager interface. This interface allows manipulation and retrieval of ACLs of resources, represented as IResourceAcl objects.
if( theSM instanceof IAclSecurityManager ) { IAclSecurityManager theASM = (IAclSecurityManager)theSM; IResourceAclManager theRASM = theASM.getAclManager(); // retrieving an ACL IResourceAcl acl = theRASM.getInheritedAcl(res); // creating a new ACL IResourceAcl iracl = irm.createAcl(resource); }
Note: The IResourceAclManager object provides two methods to access the ACL of a resource: getAcl( IResource ) and getInheritedAcl( IResource ), both of which may return null if no ACL has been assigned to that resource. Additionally, getAcl() only returns the ACL assigned directly to the resource in question, and does not provide access to ACLs that apply to a resource due to inheritance. getInheritedAcl() provides this functionality. Finally, permissions may be assigned to resource / user pairs in the following way.
// get ACLPermission IAclPermission aclperm = irm.getPermission( IAclPermission.ACL_PERMISSION_READ ); // create ACL entry IResourceAclEntry iraclentry = irm.createAclEntry( user, false, aclperm, 1 ); // add ACL entry to ACL iracl.addEntry(iraclentry);
Locking The repository framework offers locks in order to achieve serialization. An application issues a lock request for a resource and user. If there is no other blocking lock (for another user) on this resource, the application can obtain the
2006/Q2
© 2006 SAP AG. All rights reserved.
51
Unit 3: Repository Framework Concepts
EP130
lock. If a blocking lock already exists for the resource (that is, for another user), the request is denied. Furthermore, access of a particular kind (write or read) is only allowed for users who obtain the relevant lock. A simple locking scenario is illustrated by the following code block.
IResource res = ... ; ILockInfo theLockInfo = null; try { theLockInfo = res.lock(); // process locked resource here // ... } finally { if( res.isLocked() ) { res.unlock( theLockInfo ); } }
Note: the lock/unlock operation is protected by a try / finally block to avoid leaving resources in a locked state in case the program flow is interrupted by an exception after the resource has been locked. Not using a try / finally block is a common mistake and will result in resources remaining locked after program execution. A catch block may be added here to handle individual errors, but the finally block is key to avoid this problem. More fine-grained control over the locking of resources can be achieved by using the IResource.lock( ILockProperties ) method. The ILockProperties object allows the specification of parameters that are used by the underlying locking mechanism. For example, the following code sample illustrates how obtain an exclusive write lock on a resource. A timeout of 300 seconds has been given, after which the lock will expire if not released through a call to IResource.unlock().
IResource res = ...; ILockInfo theLockInfo = null; try { ILockProperties theLockProperties = new LockProperties(LockType.WRITE, LockScope.EXCLUSIVE, LockDepth.SHALLOW, 300 ); theLockInfo = res.lock(theLockProperties);
52
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
// process locked resource here // ... } finally { if( res.isLocked() ) { res.unlock( theLockInfo ); } }
Versioning The repository framework layer provides versioning functionality for resources (but not collections). Versioning can be enabled or disabled on a per-collection basis in KM. If a user is working without versioning enabled, then only the current version of a resource exists in the portal. Any changes to the document will overwrite the old version of the document, which can then no longer be retrieved. When versioning is enabled, each version of the document is retained in the system. The user can access the entire version history of a document to display and restore old document versions. At the API level, version information is accessed via three main methods on the IResource interface: • • • •
IResource.isVersioned(), which returns true if a resource has versioning enabled IResource.isRevision(), which returns true if the resource in question is a revision within a version history IResource.getRevisionID(), which returns a revision identifier (String) for the resource IResource.getVersionHistory(), which returns an IVersionHistory object that allows access to the resource's version history.
The following code sample shows how to enable versioning programatically, as well as how to retrieve basic version information and how to create a new version by checking out a resource.
// Enable versioning in root collection root.enableVersioning(true); IResource res = ResourceFactory.getInstance().getResource(new RID("/pre/test.txt“), context); res.getRevisionID(); // Returns 1 // Create a new version of the resource - Check out
2006/Q2
© 2006 SAP AG. All rights reserved.
53
Unit 3: Repository Framework Concepts
EP130
res.checkOut();
The content of the resource can be updated during check-in by passing a new IContent object to the IResource.checkIn() method. Notice also that the RID for a revision of a resource is distinct from the RID of the main resource (or current revision).
Content content = new Content( new ByteArrayInputStream("new content".toBytes()), "text/plain", -1L); res.checkIn(content, null); // Version history IVersionHistory hist = res.getVersionHistory(); hist.size(); // returns 2 hist.getRevision("2").getContent(); // New content hist.getRevision("2").getRID(); // New RID, like this: // /pre/test.txt/~versions~/2.
Hint: The RFExplorer tool is a good way to browse the low-level information available in a repository. Using this tool will also help you understand some of the concepts here. You can find this tool on SDN by searching for “RFExplorer”. Please read the article that explains its installation and use.
54
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Exercise 2: Using the Repository Framework API from Within an iView Exercise Objectives After completing this exercise, you will be able to: • Perform basic operations on repository objects using the Repository Framework API
Business Example Your system administrator has asked you to develop a set of basic iViews to help debug and maintain the system. You do this by creating a set of iViews that make direct use of the functionality provided by the Repository Framework API.
Task: When approaching new development tasks in KM, it is often helpful to first implement the logic in an iView in order to test subunits of the new component, rather than attempting to create a complete component without testing the individual parts. An example of this might be the creation of a new namespace or content filter (covered in later lessons). Debugging filters can be difficult, since they are faceless components and do not easily allow interaction with a testing user. Setting up some simple iViews allow for this direct interaction.
2006/Q2
1.
Display a directory listing of a directory given as a URL parameter (one iView).
2.
Display all available properties of a resource given as a URL parameter (one iView).
3.
Display the version history of a resource if it has versioning enabled. Show the display name property and version number for each version.
4.
Check to see if a resource is a link. If it is an internal link, check if the link target exists. Also check if the link points to a parent of itself and show a warning if it does.
© 2006 SAP AG. All rights reserved.
55
Unit 3: Repository Framework Concepts
EP130
Solution 2: Using the Repository Framework API from Within an iView Task: When approaching new development tasks in KM, it is often helpful to first implement the logic in an iView in order to test subunits of the new component, rather than attempting to create a complete component without testing the individual parts. An example of this might be the creation of a new namespace or content filter (covered in later lessons). Debugging filters can be difficult, since they are faceless components and do not easily allow interaction with a testing user. Setting up some simple iViews allow for this direct interaction. 1.
Display a directory listing of a directory given as a URL parameter (one iView). a)
public class ShowDirectoryListing extends AbstractPortalComponent { private IPortalComponentResponse response;
public void doContent( IPortalComponentRequest request, IPortalComponentResponse response) { this.response = response; try { IResourceContext ctx = getContext(request); String s = request.getParameter("rid"); if (s == null) { response.write("URL parameter 'rid' is required"); return; }
RID rid = RID.getRID(s); IResource resource = ResourceFactory.getInstance().getResource(rid, ctx); if (resource.isCollection()) { ICollection col = (ICollection) resource;
Continued on next page
56
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
for (IResourceListIterator i = col.getChildren().listIterator(); i.hasNext(); ) { IResource r = i.next(); // Show just the display name of the resource - if this is not // set, then the RID name is used (boolean argument to method cal // put HTML < br > in output for new line response.write(r.getDisplayName(true) + " "); } } else { response.write( "Resource " + rid + " is not a directory. Directory listing not possible."); return; } } catch (Exception e) { reportError(e); } } private void reportError(Exception e) { response.write( "An error occurred processing the request. Technical info: " + e.getClass().getName() + ": " + e.getMessage()); } private IResourceContext getContext(IPortalComponentRequest request) throws UserManagementException { IUser ep5user = WPUMFactory.getUserFactory().getEP5User(request.getUser()); ResourceContext ctx = new ResourceContext(ep5user); return ctx; }
Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
57
Unit 3: Repository Framework Concepts
EP130
}
Continued on next page
58
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
2.
Display all available properties of a resource given as a URL parameter (one iView). a)
Using the same skeleton and helper methods as the iView above, a method to dump the properties of a resource could be implemented in the following way.
public void showProperties( IPortalComponentRequest request, IPortalComponentResponse response) { this.response = response; try { IResourceContext ctx = getContext(request); String s = request.getParameter("rid"); if (s == null) { response.write("URL parameter 'rid' is required"); return; } RID rid = RID.getRID(s); IResource resource = ResourceFactory.getInstance().getResource(rid, ctx); IPropertyMap map = resource.getProperties();
response.write(" Properties of" + rid + " "); for( IPropertyIterator i = map.iterator(); i.hasNext() ;
)
{ IProperty p = i.next(); response.write(
p.getPropertyName().toString() + ": ");
response.write( p.getValueAsString() + " "); } } catch (Exception e) { reportError(e); } }
3.
Display the version history of a resource if it has versioning enabled. Show the display name property and version number for each version. Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
59
Unit 3: Repository Framework Concepts
a)
EP130
Using the same skeleton and helper methods as the iView above, a method to show the version history of a resource could be implemented in the following way.
private void showVersionHistory( IPortalComponentRequest request, IPortalComponentResponse response) { this.response = response; try { IResourceContext ctx = getContext(request); String s = request.getParameter("rid"); if (s == null) { response.write("URL parameter 'rid' is required"); return; }
RID rid = RID.getRID(s); IResource resource = ResourceFactory.getInstance().getResource(rid, ctx); if (resource.isVersioned()) {
IVersionHistory history = resource.getVersionHistory(); for (IResourceListIterator i = history.listIterator(); i.hasNext(); ) { IResource r = i.next(); String name = r.getDisplayName(true); String id = r.getRevisionID(); response.write(name + " " + id + HTML_BR); } } else { response.write("Resource " + rid + " is not versioned."); } } catch (Exception e) { reportError(e);
Continued on next page
60
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
}
}
4.
Check to see if a resource is a link. If it is an internal link, check if the link target exists. Also check if the link points to a parent of itself and show a warning if it does. a)
Using the same skeleton and helper methods as the iView above, a method to show link information could be implemented in the following way.
private void checkLinkStatus( IPortalComponentRequest request, IPortalComponentResponse response) { this.response = response; try { IResourceContext ctx = getContext(request); String s = request.getParameter("rid"); if (s == null) { response.write("URL parameter 'rid' is required"); return; } RID rid = RID.getRID(s); IResource resource = ResourceFactory.getInstance().getResource(rid, ctx); if( resource == null ) { response.write("Resource " + rid + " does not exist."); return; } if ( LinkType.NONE.equals( resource.getLinkType() )) { response.write("Resource " + rid + " is not a link." + HTML_BR ); } else if ( LinkType.EXTERNAL.equals( resource.getLinkType() )) { response.write("Resource "
Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
61
Unit 3: Repository Framework Concepts
EP130
+ rid + " is an external link." + HTML_BR); } else if ( LinkType.INTERNAL.equals( resource.getLinkType() )) { response.write("Resource " + rid + " is an internal link." + HTML_BR); IResource target = resource.getTargetResource(); if( target != null ) { RID targetRID = target.getRID(); if( targetRID.isAncestorOf( resource.getRID() ) ) { response.write("Link points to ancestor of itself. This is potentially dangerous."); } else { response.write("Link target exists."); } } else { response.write("Target resource of link does not exist."); } } } catch (Exception e) { reportError(e); } }
62
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Framework Concepts
Lesson Summary You should now be able to: • Explain the role and function of the repository framework layer within the KM architecture stack • List the components that make up the repository framework layer • Describe how information is structured in KM
2006/Q2
© 2006 SAP AG. All rights reserved.
63
Unit Summary
EP130
Unit Summary You should now be able to: • Explain the role and function of the repository framework layer within the KM architecture stack • List the components that make up the repository framework layer • Describe how information is structured in KM
64
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 4 Repository Filters Unit Overview Repository filters play a central role in extending the functionality of KMC. They are flexible and powerful, and understanding them is critical to a well-behaving and well-performing system. This unit covers the basics of the three types of repository filters that are made available via the KMC API.
Unit Objectives After completing this unit, you will be able to: •
Develop new custom filters
Unit Contents Lesson: Repository Filters ...................................................... 66 Exercise 3: Developing a Namespace Filter ............................. 71
2006/Q2
© 2006 SAP AG. All rights reserved.
65
Unit 4: Repository Filters
EP130
Lesson: Repository Filters Lesson Overview In this lesson, we will discuss the three basic types of repository filters and their modes of operation. We will also show an example of a namespace filter.
Lesson Objectives After completing this lesson, you will be able to: •
Develop new custom filters
Business Example You have been asked to develop logic in KM that hides all resources that have a name that begin with an underscore (“_”) from all users except users belonging to a certain group. You decide that setting permissions on these resources to hide them isn't appropriate, since everyone should still be able to access the files, and they are in many different locations in the hierarchy. You decide that the best way to do this is to write a simple namespace filter that checks the calling user's group membership and hides these resources as appropriate.
Repository Filters Repository filters are a very powerful tool that can be used to accomplish various types of basic tasks within KM. At the same time, misusing or implementing a filter poorly can have serious consequences on performance and accessibility of information stored in KM. Therefore it is important to thoroughly understand filters before implementing one. Repository filters function in one of two basic modes: read or write. Read filters are triggered during read operations (for example, content retrieval, directory listing, or property retrieval) and change what the end user sees without affecting the content or structure in KM. Write filters are triggered during write operations (for example, saving content or properties of resources) and generally change the content or structure of data in KM when they run.
66
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Filters
In addition to these two modes of operation, there are three basic types of filters in KM: •
Namespace filters –
•
Hide existing resources from the hierarchy; namespace filters function only in read mode Property filters –
•
Hide or modify existing properties of resources, or add virtual properties to resources Content filters –
Modify a resource's content during either content retrieval (reading the content of a resource) or during a save operation
Note that content and property filters function in either read or write mode, but that namespace filters can function only in read mode.
Figure 24: Filter Architecture
Filters are applied sequentially. When a client requests a read operation (this can be content or property retrieval, or a directory listing), the repository framework retrieves the specified resource data from the repository manager. It then retrieves the last filter to apply from the read filter manager by requesting the filter from that manager. The filter logic is then applied by calling the appropriate method on the filter. The filter processes the request by invoking the corresponding method on its predecessor filter. Finally the filtered data is returned to the client.
Filters and Filter Managers After running the filter creation wizard, you have two class skeletons to work with: the main filter class and the filter manager class.
2006/Q2
© 2006 SAP AG. All rights reserved.
67
Unit 4: Repository Filters
EP130
Figure 25: Filter Invocation: Sequence Diagram
The repository filter manager decides when to apply a filter. When the repository framework requests the filters to be applied from the repository filter manager, it uses getFilterForRead() when a read request's data has to be filtered, and getFilterForWrite() when a write request's data is to be filtered. The filter's predecessor in the filter chain is passed as a parameter to the getFilterFor…() method. The filter manager should then decide (based on the resource returned by the predecessor's filter getResource() method) whether to apply its filter or not. If the filter is to be applied, the filter manager should return its own filter. If the filter should not be applied, it must return the predecessor as passed to the getFilter…() method. The filter manager must not return null. For property and namespace filters, the main processing occurs in the filter() method on the filter class. This method is called by the framework when applying the filter to a certain resource. Because a filter cascade could be applied (filters are invoked in a chain, as discussed above), it is necessary to retrieve the result from the predecessor's filter() method and use this as a basis for further processing. For a namespace filter, the filter() method returns an IResourceList. For a property filter, this method will return an IPropertyMap object. Content filters are slightly different in this regard, since they do not have a filter() method. Instead, the content of the predecessor is manipulated using the getInputStream() method. Additionally, the content length, content type and encoding of the content can also be modified using the appropriate access methods (getContentLength(), getContentType(), getEncoding()).
68
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Filters
Caution: Because filters are called on a per-user-request basis, it's important to implement filters to perform according to strict performance guidelines. Inefficiencies in filters will cause a higher than necessary load on the system. As usual, attaining good performance means paying particular attention to the algorithms and order of operations used.
Example: Namespace filter • • •
Affects the visibility of resources and is applied to collections Implements INamespaceFilter The filter's getCollection() method returns the collection to which the filter is to be applied The filter's filter() method returns the filtered list of child resources for the collection
•
A filter component consists of a filter manager class, which controls the filter itself, and a filter implementation.
Sample coding for a Namespace filter manager public MyNamespaceFilterManager extends AbstractNamespaceFilterManager { public INamespaceFilter getFilterForRead( INamespaceFilter impPreFilter, NamespaceFilterMode mode) throws WcmException{ if (mode.equals(NamespaceFilterMode.GET_CHILDREN) ||mode.equals(NamespaceFilterMode.GET_RESOURCE) ) { return new CollectionFilter(impPreFilter); } return impPreFilter; } ... }
Caution: Like many components in KMC development, repository filters can be difficult to debug, since they are faceless and interaction with them is indirect and triggered through interacting with repositories. For this reason, is it strongly recommended that you use the Logging and Tracing API for basic tracing and debugging tasks as you get started with your filters. For clarity, tracing code is omitted from the code samples in this lesson.
2006/Q2
© 2006 SAP AG. All rights reserved.
69
Unit 4: Repository Filters
EP130
This sample of a Namespace filter manager shows a manager that returns a custom filter object to the framework when the filter mode is either GET_CHILDREN or GET_RESOURCE. If the mode is not either of these values, the predecessor filter from the filter chain is returned; that is, the custom filter CollectionFilter is skipped.
Sample coding for a Namespace filter public MyNamespaceFilter implements INamespaceFilter { public I get() throws WcmException { return this.predecessorFilter.get(); } ...
The filter must implement the INamespaceFilter interface.
Sample coding for a Namespace filter public IResourceList filter() throws
WcmException
{ IResourceList resourceList = this.predecessorFilter.filter(); IResourceListIterator resourceListIterator = resourceList.listIterator(); while(resourceListIterator.hasNext()) { if (resource.getLinkType().equals( LinkType.INTERNAL)) { resourceListIterator.remove(); } } return resourceList; ...
70
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Filters
Exercise 3: Developing a Namespace Filter Exercise Objectives After completing this exercise, you will be able to: • Develop a simple repository filter
Business Example Your project has requested that you develop a component that hides file resources and shows only collections (and hides file resources) for a particular branch of the KM hierarchy. You decide that the best way to do this is to develop a namespace filter.
Task: Set up a new project in NetWeaver Develop Studio and run the namespace filter wizard. 1.
Create a portal application project named “MyCollectionFilter” and then use the KMC Wizard to create a new namespace filter called “MyCollectionFilter” in the package “com.sap.learning.km.filter”
2.
Update the value of the KEY variable in the IRFServiceWrapper to a unique value. You can use “com.sap.learning.km.filter.MyCollectionFilter”.
3.
Make sure that you have the correct JAR files in your classpath so that no build errors are shown in Developer Studio.
4.
Modify the method getFilterForWrite() in MyCollectionFilterManager so that it returns predecessorFilter instead of null.
public INamespaceFilter getFilterForWrite(INamespaceFilter predecessorFilter) throws WcmException { return predecessorFilter; }
5.
2006/Q2
Implement the logic required to filter out file resource but leave collections in the directory listing.
© 2006 SAP AG. All rights reserved.
71
Unit 4: Repository Filters
EP130
Solution 3: Developing a Namespace Filter Task: Set up a new project in NetWeaver Develop Studio and run the namespace filter wizard. 1.
Create a portal application project named “MyCollectionFilter” and then use the KMC Wizard to create a new namespace filter called “MyCollectionFilter” in the package “com.sap.learning.km.filter” a)
2.
You should have a new project with four java classes in it, as in the following screenshot.
Update the value of the KEY variable in the IRFServiceWrapper to a unique value. You can use “com.sap.learning.km.filter.MyCollectionFilter”. a)
public interface IRFServiceWrapper extends IService{ public static final String KEY = "com.sap.learning.km.filter.MyCollectionFilter"; }
3.
Make sure that you have the correct JAR files in your classpath so that no build errors are shown in Developer Studio. a)
4.
You will need bc.util.public_api.jar. bc.rf.framework_api.jar and bc.crt_api.jar.
Modify the method getFilterForWrite() in MyCollectionFilterManager so that it returns predecessorFilter instead of null.
public INamespaceFilter getFilterForWrite(INamespaceFilter predecessorFilter) throws WcmException { return predecessorFilter; }
a) 5.
as described
Implement the logic required to filter out file resource but leave collections in the directory listing. a)
The body of the main filter class should look like this.
Continued on next page
72
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Filters
package com.sap.learning.km.filter; import com.sapportals.wcm.WcmException; import com.sapportals.wcm.repository.ICollection; import com.sapportals.wcm.repository.IResource; import com.sapportals.wcm.repository.IResourceList; import com.sapportals.wcm.repository.IResourceListIterator; import com.sapportals.wcm.repository.filter.INamespaceFilter; public class MyCollectionFilter implements INamespaceFilter { private final INamespaceFilter predecessorFilter;
MyCollectionFilter(INamespaceFilter predecessorFilter) { this.predecessorFilter = predecessorFilter; } public IResourceList filter() throws WcmException { IResourceList list = this.predecessorFilter.filter();
for (IResourceListIterator i = list.listIterator(); i.hasNext();) { IResource r = i.next(); if (!r.isCollection()) { i.remove(); } } return list; } public ICollection getCollection() throws WcmException { return this.predecessorFilter.getCollection(); } }
b)
The body of the filter manager class should look like this.
Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
73
Unit 4: Repository Filters
EP130
package com.sap.learning.km.filter;
import com.sapportals.wcm.WcmException; import com.sapportals.wcm.crt.component.StartupException; import com.sapportals.wcm.crt.configuration.ConfigurationException; import com.sapportals.wcm.repository.enum.NamespaceFilterMode; import com.sapportals.wcm.repository.filter.AbstractNamespaceFilterManager; import com.sapportals.wcm.repository.filter.INamespaceFilter; public class MyCollectionFilterManager extends AbstractNamespaceFilterManager { public MyCollectionFilterManager() { super(); // Do not add code here. Add it to startUpImpl() instead ! } public INamespaceFilter getFilterForRead( INamespaceFilter predecessorFilter, NamespaceFilterMode mode) throws WcmException { return new MyCollectionFilter(predecessorFilter); }
public INamespaceFilter getFilterForWrite(INamespaceFilter predecessorFilter) throws WcmException { return predecessorFilter; }
protected void startUpImpl() throws ConfigurationException, StartupException { }
protected void shutDownImpl() { } }
74
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Filters
Lesson Summary You should now be able to: • Develop new custom filters
2006/Q2
© 2006 SAP AG. All rights reserved.
75
Unit Summary
EP130
Unit Summary You should now be able to: • Develop new custom filters
76
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 5 Repository Managers Unit Overview Repository managers are the primary method of integrating third-party back-end systems with Knowledge Management in the portal. They play a central role in any KMC installation, and understanding them is a prerequisite to developing a custom repository manager. This unit covers the basics of repository manager architecture and will help you understand the effort involved in developing a custom, minimal repository manager. We will also discuss extending minimal functionality into a more realistic, real-world scenario.
Unit Objectives After completing this unit, you will be able to: • • • • • • • • •
Explain how repository managers are integrated into the repository framework List the components of a repository manager Explain how the development tools support creation of repository managers Explain the basics of implementing core repository manager functionality Describe how aspects (feature sets) are implemented Define a mutable extension Implement a mutable aspect Explain what the security checker is for Use the security checker in your own code
Unit Contents Lesson: Repository Manager Concepts ...................................... 79 Exercise 4: Developing a Read-Only Repository Manager ............ 85 Lesson: Development Tools .................................................... 88 Exercise 5: Development Tools for Repository Managers ............. 95 Lesson: Implementing the Repository Manager ............................. 98 Lesson: Mandatory Aspects ...................................................103 Lesson: Mutable Extensions .................................................. 110 Lesson: Using the Security Checker ......................................... 118
2006/Q2
© 2006 SAP AG. All rights reserved.
77
Unit 5: Repository Managers
EP130
Exercise 6: Mandatory Aspects, Mutable Extensions, and the Security Checker ......................................................................121
78
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Manager Concepts
Lesson: Repository Manager Concepts Lesson Overview Repository managers are the primary method of integrating third-party back-end stores into Knowledge Management. This lesson outlines the basic principles you will need when implementing your own repository manager.
Lesson Objectives After completing this lesson, you will be able to: • •
Explain how repository managers are integrated into the repository framework List the components of a repository manager
Business Example Your corporation has a 3rd-party backend system that is used to store and manage information about the widgets that your company manufactures. You would like to integrate this backend through KM to make the information that is stored there available to your portal users via the familiar KM interface, allowing browsing and searching of the backend data. You decide that the best way to do this is to implement a custom respository manager.
Repository Managers Within KMC Architecture
Figure 26: Review of Repository Managers Within KMC Architecture
2006/Q2
© 2006 SAP AG. All rights reserved.
79
Unit 5: Repository Managers
EP130
Notice that the repository manager API is part and makes direct use of the repository framework layer. Custom developed repository managers are treated as KMC applications in this model, and are therefore present in the topmost layer.
Figure 27: Repository Managers and Other Extensions
80
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Manager Concepts
The following are types of repository framework extensions: •
Repository managers handle the mapping between the repository framework objects and the back-end system (information source). For example, the File System repository manager maps files and directories of the file system to resources and collections.
•
Repository filters allow the manipulation of repository framework objects as they are passed through the repository framework. For example, the HTML Stylesheet filter applies a CSS to resources with content type text/html.
•
Repository services offer additional unified aspects for the resources of a specific repository. For example, the Application Properties service offers additional properties to be stored along with a resource, which an application might use to save additional data for that resource, such as a timestamp that indicates the application-specific lifetime of a resource.
•
Global services offer additional unified aspects for all repository framework resources. For example, the Relation service allows storage and retrieval of relations between resources, which an application might use to save interdependency information about resources, such as “document X is attached to document Y.”
•
Semantic objects represent some special aspects of the resource objects. For example, a resource might be converted into the semantic object “Team Room.”.
2006/Q2
© 2006 SAP AG. All rights reserved.
81
Unit 5: Repository Managers
EP130
Figure 28: Connecting a Back-End System Through a Repository Manager
There are two ways to connect a back-end system through a repository manager to the repository framework: •
•
82
A repository manager implements a Java stub that communicates through a dedicated protocol (for example, http) with the source system. This is the recommended integration method. A repository manager implements a Java stub thath communicates through the same Java stack with a proprietary stub of the source system. Communication between the proprietary stub and the back-end system is handled by a protocol determined by the stub vendor.
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Manager Concepts
Figure 29: Repository Manager and Sub-Manager Class Hierarchy
A repository manager has to be derived from mi.AbstractManager. This base class handles the various interfaces that are required for interaction with the component runtime and handles registration with the manager registry. The AbstractManager's methods startUpImpl() and shutDownImpl() can be overwritten by the repository manager if something must be initialized on startup (for example, if a connection to the back-end system has to be established) or must be de-initialized on shutdown (for example, when the connection has to be closed again). To implement the functions for the various resource aspects, the repository manager might contain several sub-managers, one for each aspect of a resource. All these aspects – and therefore the sub-managers that implement the aspect's functionality – are optional. The repository manager's sub-managers have to be derived from mi.AbstractSubManager. As for the mi.AbstractManager, the mi.AbstractSubManager's methods startUpImpl() and shutDownImpl() can be overwritten by the sub-manager implementation, if initialization or de-initialization are required during startup or shutdown. Repository managers: • • • • • •
2006/Q2
Must be derived from mi.AbstractManager Can implement a default constructor (without parameters) Must implement the getSupportedOptions() method Must implement the various lookup() methods Should implement the getNameInfo() method Can implement startUpImpl() and shutDownImpl()
© 2006 SAP AG. All rights reserved.
83
Unit 5: Repository Managers
EP130
Sub-managers (aspects): • • • • •
Must be derived from mi.AbstractSubManager Must implement a constructor that takes the mi.IManager as parameter Must implement one of the read-only aspects Can implement startUpImpl() and shutDownImpl() Can implement the mutable interface for the aspect it implements
Components of a repository manager Manager Interface APIs: • •
com.sap.netweaver.bc.rf.common.* com.sap.netweaver.bc.rf.mi.*
•
– Abstract classes and interfaces Old APIs not to be used in RM implementations – – –
com.sapportals.wcm.repository.* Including all sub-packages com.sapportals.wcm.service.*
The com.sap.netweaver.bc.rf.common.* package contains shared classes that can be used either by the server-side API (MI API) or by the client side API. The com.sap.netweaver.bc.rf.mi.* package and its sub-packages offer a set of abstract classes to be extended and interfaces to be implemented by certain aspects of the repository manager.
84
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Manager Concepts
Exercise 4: Developing a Read-Only Repository Manager Exercise Objectives After completing this exercise, you will be able to: • Develop the mandatory aspects Namespace, Content, and Properties for a repository manager implementation
Business Example This exercises outlines the basic steps required when implementing any new repository manager.
Task: Develop a read-only repository manager 1.
2006/Q2
Follow the TODO tags in the exercise project.
© 2006 SAP AG. All rights reserved.
85
Unit 5: Repository Managers
EP130
Solution 4: Developing a Read-Only Repository Manager Task: Develop a read-only repository manager 1.
Follow the TODO tags in the exercise project. a)
86
–
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Repository Manager Concepts
Lesson Summary You should now be able to: • Explain how repository managers are integrated into the repository framework • List the components of a repository manager
2006/Q2
© 2006 SAP AG. All rights reserved.
87
Unit 5: Repository Managers
EP130
Lesson: Development Tools Lesson Overview This lesson introduces the Repository Manager wizard in SAP NetWeaver Developer Studio.
Lesson Objectives After completing this lesson, you will be able to: •
Explain how the development tools support creation of repository managers
Business Example The tools discussed in this lesson are useful (although not necessarily required) for custom development of repository managers.
SAP NetWeaver Developer Studio Support for Developing Repository Managers The repository manager wizard integrated into SAP NetWeaver Developer Studio is supplied to aid in the generation of code and structure required for your repository manager implementation. Repository managers are the most complex component of a KM installation, and developing one from scratch involves a lot of programming. Therefore, this wizard also outputs considerably more code than the other KMC wizards. The wizard will generate the code skeletons required for the aspects that you select when you run the wizard. Aspects are feature sets that are discussed in more detail in later lessons. In addition to the skeletons for selected aspects, the wizard outputs logging code that is put in place to help you develop and debug your repository manager. Like the other wizards used in KMC development, the repository manager wizard also output configuration classes and configurable instances for the repository manager, as well as the portal deployment descriptor and service registration classes discussed in Unit 2. You can find the Repository Manager Wizards by choosing File → New → Repository Manager Wizard.
88
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Development Tools
Figure 30: Accessing the Wizard
The screenshot below shows the selection of aspects during wizard execution. As you can see, there are a total of eight aspects that can be implemented, each with a read-only or a mutable version. Additionally, the version aspect allows the distinction between using advanced or basic base classes on which to base your implementation.
Figure 31: Working with Aspects
2006/Q2
© 2006 SAP AG. All rights reserved.
89
Unit 5: Repository Managers
EP130
The following table gives an overview of the JAR files that need to be included in a repository manager project along with the functionality (API) that is supplied by each JAR file. These libraries are mandatory. Depending on your implementation, you may need additional libraries. JAR file
Supplied API
bc.crt_api.jar
CRTClassLoader
bc.rf.ci_api.jar
client interface API
bc.rf.common_api.jar
common interface API
bc.rf.framework_api.jar
“old” client interface API
bc.rf.manager.crt_api.jar
manager lifecycle interface API
bc.rf.manager.sub_acl_api.jar
security manager API
bc.rf_mi_api.jar
manager interface API
bc.rf.runtime_api.jar
repository framework runtime
bc.rf.util_api.jar
utility classes, e.g. de-/encoder
bc.sf.framework_api.jar
service framework API
If you take a look at the generated code, you will notice the logging calls that are output by the wizard. Also, notice that the most restrictive access modifiers are used where applicable (method access modifiers), and that the super implementation is called where necessary.
/** * Construct new repository manager. */ public SimpleRepositoryManager() { logger.infoT("SimpleRepositoryManager(< line >)", "SimpleRepositoryManager successfully initialized."); } /** * Start up repository manager. */ protected void startUpImpl() throws ConfigurationException, StartupException { super.startUpImpl(); logger.infoT("startUpImpl(< line >)", "SimpleRepositoryManager successfully started up."); }
90
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Development Tools
/** * Shut down repository manager. */ protected void shutDownImpl() { super.shutDownImpl(); logger.infoT("shutDownImpl(< line >)", "SimpleRepositoryManager successfully shut down."); }
Logging information is logged into the standard trace file of the SAP NetWeaver Application Server: defaultTrace.#.trc. Note: whether or not logging information is output and the exact location of log output is determined by configuration of the NetWeaver Application Server. Please refer to the Logging and Tracing guide on help.sap.com for information on how to effectively use this framework in development and production environments. The logging output can be read by: • •
A text editor The log viewer tool of the SAP NetWeaver Application Server
It is considerably easier to read the logs using the log viewer tool. The following source code shows that methods that are not implemented throw a corresponding exception. This is the correct behavior for a repository manager: unimplemented methods should throw an exception instead of returning null values.
/* *
(non-Javadoc)
*
@see com.sap.netweaver.bc.rf.mi.IManager#lookup(java.util.List,
*
boolean, java.util.List)
*/ public List lookup( List ridList, boolean contentToBeFetched, List propertyNamesToBeFetched) throws ResourceException, OperationNotCompletedException { // Safeguard operations try { // Protocol method entering logger.entering("lookup(< line >)",
2006/Q2
© 2006 SAP AG. All rights reserved.
91
Unit 5: Repository Managers
EP130
new Object[] {ridList, new Boolean(contentToBeFetched), propertyNamesToBeFetched}); // TBD: Return resource handle for resource ids throw new OperationNotSupportedException( null, "Multiple resource lookup not yet supported!", true); } finally { // Protocol method exiting logger.exiting(); } }
Notice that the wizard also generates the necessary configuration information for the deployable unit, just like the KMC wizard used to generate the repository filter skeleton. In general, these XML files may be modified to add to your implementation. In the diagram below, an attribute called “OSRoot” has been added to the meta information for a repository manager. This value can then be maintained at configuration time using the KM configuration iView in the portal, and can also be accessed by the repository manager implementation at runtime.
Figure 32: Extending the Configuration with Custom Attributes: Class
The following diagram shows the configuration of the instance of the repository manager, where concrete values are assigned to the attributed defined in the class (meta) definition of the configurable object.
92
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Development Tools
Figure 33: Extending the Configuration with Custom Attributes: Instance
Finally, a repository manager deployable unit can be deployed to a server in the same way that most custom KMC components are deployed - using hot deployment (which is strongly discouraged), or by placing the PAR file in the deployment directory of the NetWeaver Application Server.
Figure 34: Hot Deployment of the Repository Manager
2006/Q2
© 2006 SAP AG. All rights reserved.
93
Unit 5: Repository Managers
94
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Development Tools
Exercise 5: Development Tools for Repository Managers Exercise Objectives After completing this exercise, you will be able to: • Use the wizard in SAP NetWeaver Developer Studio to create a repository manager skeleton
Business Example Using the wizard is necessary whenever a new repository manager is to be created.
Task: Create a new portal project and run the Repository Manager wizard 1.
2006/Q2
Create a new portal project and use the wizard to generate a skeleton for a repository manager.
© 2006 SAP AG. All rights reserved.
95
Unit 5: Repository Managers
EP130
Solution 5: Development Tools for Repository Managers Task: Create a new portal project and run the Repository Manager wizard 1.
96
Create a new portal project and use the wizard to generate a skeleton for a repository manager. a)
Name the portal project whatever you wish. A good name might be SimpleRMTest.
b)
Right-click on the project and choose the Repository Managers Generation wizard from the context menu.
c)
Uncheck the Generate project classpath with BC libraries from plug-in box.
d)
Name your repository manager MySimpleRM. Give it a Java package using your name, for example, com.john.test.rm. Give it the prefix simplerm.
e)
Select the non-mutable versions of the content, namespace, and property sub-managers for generation.
f)
Go into the IRFServiceWrapper class and change the key to a unique value. In this case, com.john.test.rm.MySimpleRMRepositoryManager would be a good choice.
g)
Have a look at the generated code. Notice the logging information that is output. View the relationship between the generated classes. Look into the configuration files.
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Development Tools
Lesson Summary You should now be able to: • Explain how the development tools support creation of repository managers
2006/Q2
© 2006 SAP AG. All rights reserved.
97
Unit 5: Repository Managers
EP130
Lesson: Implementing the Repository Manager Lesson Overview This lesson covers the basics of implementing core repository manager functionality and the core operation of this central class, the RID lookup operation. We will also discuss the supported options of the repository manager, as well as accessing the user context.
Lesson Objectives After completing this lesson, you will be able to: •
Explain the basics of implementing core repository manager functionality
Business Example Your employer has asked you to develop a repository manager in order to integrate a 3rd-party backend into KM. You start out by implementing a minimal repository manager for testing purposes, and off of which to base your further development.
Basics of Implementing Repository Manager Functionality A minimum implementation of a repository manager is a lookup for RIDs. There are no functions defined for content retrieval, resource manipulation, or namespace actions.
Figure 35: RID Lookup
A sample implementation of the lookup() method is a recursive implementation to resolve the requested RID object.
98
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Implementing the Repository Manager
Figure 36: Implementation of RID Lookup
If the back-end system supports a faster calculation of the referenced objects, it is preferred to use a back-end call. This is because the lookup() method is called several times for a single resource request from the KM application Hint: The lookup() method must return a null value if the RID object passed through the method is null.
Figure 37: getSupportedOptions() Method
2006/Q2
© 2006 SAP AG. All rights reserved.
99
Unit 5: Repository Managers
EP130
To indicate which operations are supported for a given object, the repository manager must implement the getSupportedOptions() method, which receives an IResourceHandle as a parameter and returns a set of supported options for the type of object to which the handle refers. If the handle is null, getSupportedOptions() should return all options it supports.
Figure 38: Context Information
Before an operation is requested from the repository manager, the resource’s access context is pushed to the current thread’s context by the repository framework using a common.context.AccessContextFactory. The repository manager retrieves the access context through AccessContextFactory. This technique eliminates the resource’s access context as an additional parameter on each call to the manager, making the signatures of several methods less complicated. The following figure shows an implementation of getUserFromContext() for retrieving the information from the access context.
100
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Implementing the Repository Manager
Figure 39: Accessing Context Information
2006/Q2
© 2006 SAP AG. All rights reserved.
101
Unit 5: Repository Managers
EP130
Lesson Summary You should now be able to: • Explain the basics of implementing core repository manager functionality
102
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mandatory Aspects
Lesson: Mandatory Aspects Lesson Overview This lesson outlines the minimum amount of effort involved in implementing a basic repository manager, and can be used to get an idea of what a realistic repository manager implementation would look like. .
Lesson Objectives After completing this lesson, you will be able to: •
Describe how aspects (feature sets) are implemented
Business Example Your customer has asked you to estimate the amount of time it would take to develop a repository manager to access their 3rd party back-end with write access. You realize this is a complicated task, and so you propose a proof-of-concept project based on a minimal repository manager, on which all further work and estimates are based.
Mandatory Aspects of a Repository Manager Aspects to be implemented for a minimal, functional system •
Namespace manager (read-only)
•
– Resolves the relation between parent and child elements – Exposes navigation structures – Utilizes order mechanism and manages resource types Content manager (read-only) –
•
Delivers content of a requested handle
Property manager (read-only) –
Manages metadata
The Namespace manager aspect determines the parent-child relationship and delivers a set of child elements corresponding to a parent IResourceHandle and an IFindResourcesDescriptor object (the arguments are not shown in this example). A more advanced implementation of this method is capable of restricting the result set and performing a deep search, depending on what is required.
2006/Q2
© 2006 SAP AG. All rights reserved.
103
Unit 5: Repository Managers
EP130
Figure 40: findResources() Method
The isCollection() method must determine whether a handle is a folder node (collection) object, or if it should be handled as a leaf. Content may only be requested from leaf objects. A collection is supposed to have an empty (null) content object.
Figure 41: isCollection()
The Content manager aspect must return an IContent object for a valid IResourceHandle. The IContent object must contain an InputStream, a mimetype (string), and a length (long). Collections should be treated as null content resources. The Content manager must return a null value instead of an empty IContent object.
104
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mandatory Aspects
Figure 42: Content Retrieval
In the Repository Manager API, content is represented by common.content.IContent with common.content.Content as the default implementation. A Content manager can either use the default implementation or implement its own class (which might also extend Content). IContent provides the resource's content as an java.io.InputStream using getInputStream().
Figure 43: IContent Class Diagram
The Property manager aspect uses property classes derived from those in common.property, located in mi.property. The mi.property property implementations provide additional constructors that allow for the attributes of the property to be set.
2006/Q2
© 2006 SAP AG. All rights reserved.
105
Unit 5: Repository Managers
EP130
Figure 44: Implementing Property Retrieval
The four methods serve different purposes: • • •
•
106
getProperty() gets a single property of a single resource handle. It returns null if the property is not set. getProperties() gets a single property of a list of resource handles. getAllProperties() gets a map of all properties of a single resource handle or a map of all properties of a list of resource handles (depending on what method is used). getListedProperties() gets a list of properties of a single resource handle or a list of properties of a list of resource handles (depending on what method is used).
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mandatory Aspects
Figure 45: Properties and Their Related Classes
These classes are located in common.property.* for the client applications. common.property.PropertyName defines the property names that are known to the repository framework (for example, CREATEDBY). A property sub-manager uses property classes derived from those in common.property.*, located in mi.property. The mi.property.* property implementations provide additional constructors that allow for the attributes of the property to be set. Property manager aspect: System properties
2006/Q2
property name
description
recon- prop- apsource tent erplities cation
type
COLLECTION
True, if the resource is a collection
CONTENTENCODING
Encoding of the content
x
single string
CONTENTLANGUAGE
The language the content is for
x
single string
single boolean
x
© 2006 SAP AG. All rights reserved.
107
Unit 5: Repository Managers
EP130
property name
description
recon- prop- apsource tent erplities cation
type
CONContent's length in TENTLENGTH bytes
x
single long
CONTENTTYPE
MIME type of the content
x
single string
CREATED
Resource's creation time stamp
x
single date
CREATEDBY
User ID of the resource's creator
x
single string
DESCRIPTION
Description of the resource
x
single string
DISPLAYNAME
Display name of the resource
x
single String
ETAG
Entity tag for the content
HIDDEN
True, if the resource is hidden
LINKTYPE
Code of the resource's link type
x
MODIFIED
Timestamp of the resource's last modification
x
x
x
single date
MODIFIEDBY
User ID of the resource's last modifier
x
x
x
single string
READONLY
True, if the resource is read-only
RESOURCENAME
Name part of the resource's RID
RESOURCETYPE
Resource type
single string
x x
single boolean single int
x
single boolean single string
x x
single string
Some system properties are predefined by the repository framework and should be provided by a property manager implementation.
108
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mandatory Aspects
Lesson Summary You should now be able to: • Describe how aspects (feature sets) are implemented
2006/Q2
© 2006 SAP AG. All rights reserved.
109
Unit 5: Repository Managers
EP130
Lesson: Mutable Extensions Lesson Overview This lesson introduces mutable extensions, which can be used to extend basic functionality to include write access to the integrated back-end system.
Lesson Objectives After completing this lesson, you will be able to: • •
Define a mutable extension Implement a mutable aspect
Business Example Mutable Extensions Mutable extensions for mandatory aspects: •
Namespace manager –
Create resources –
ICollection/IResource handling
•
– Delete resources – Move/rename resources Content manager
•
– Set/update content Property manager – –
Set/update single properties Set/update property lists (mass calls)
Namespace manager aspects – createResource:
110
•
Handle descriptors
• • • •
– IResourceCreateDescriptor – ICollectionCreateDescriptor Determine the parent IRID and current name Create the content data Create the metadata (properties) Store data in back end
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mutable Extensions
Figure 46: Repository Managers: createResource
Figure 47: Repository Managers: createResource()
2006/Q2
© 2006 SAP AG. All rights reserved.
111
Unit 5: Repository Managers
EP130
Figure 48: Repository Managers: Descriptor Class Diagram
Figure 49: Repository Managers: Mutable Extensions (4)
112
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mutable Extensions
Figure 50: Repository Managers: Mutable Extensions (5)
Figure 51: Repository Managers: Mutable Extensions (6)
copyResource and moveResource are optional for implementation. If not implemented, the repository framework automatically maps copy and move/rename actions to deleteResource() and createResource() sequences.
2006/Q2
© 2006 SAP AG. All rights reserved.
113
Unit 5: Repository Managers
EP130
Figure 52: Repository Managers: Mutable Extensions (7)
Hint: SupportedOption.RENAME and SupportedOption.COPY must not be specified if the repository framework should map the corresponding calls to createResource() and deleteResource().
Figure 53: Repository Managers: Mutable Extensions (8)
setContent() stores the content data in the back end. Due to the contract with the standard KMC application, collection should not have content (but can, technically).
114
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mutable Extensions
Figure 54: Repository Managers: Mutable Extensions (9)
Figure 55: Repository Managers: Mutable Extensions (10)
Figure 56: Repository Managers: Mutable Extensions (11)
2006/Q2
© 2006 SAP AG. All rights reserved.
115
Unit 5: Repository Managers
EP130
Figure 57: Repository Managers: Mutable Extensions (12)
Figure 58: Repository Managers: Mutable Extensions (13)
It is recommended that single property calls be delegated to the mass call operation.
116
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Mutable Extensions
Lesson Summary You should now be able to: • Define a mutable extension • Implement a mutable aspect
2006/Q2
© 2006 SAP AG. All rights reserved.
117
Unit 5: Repository Managers
EP130
Lesson: Using the Security Checker Lesson Overview This lesson introduces the security checker, a utility class that simplifies the implementation of security checks within a repository manager implementation.
Lesson Objectives After completing this lesson, you will be able to: • •
Explain what the security checker is for Use the security checker in your own code
Business Example The security checker is used when implementing security checks in a custom a repository manager. For instance, security manager calls are made from within repository manager methods (such as methods to find resources or retrieve content) to ensure that the current user has the necessary permissions to execute the operation.
Using the Security Checker The security checker is a utility class that simplifies the implementation of security for repository managers. It does this by centralizing security checks, thereby also simplifying the signatures of repository manager methods. Using security mechanisms: •
Security checks on resource/collection base –
Stored in back end –
–
Implement Security manager aspect
– Implement maintenance UI Stored in KMC – – – –
Using standard Security managers, for example, ACL Security manager Make use of portal user, groups, and roles concepts Predefined set of permissions UI for maintenance already available
Two different approaches are possible: • •
118
Security stored in back end Securty stored in KMC
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Security Checker
Figure 59: Using the Security Checker
The checkXXX() method of the security checker throws an AccessDeniedException if the user with the current access context has no permission on the requested handle.
Figure 60: Using the Security Checker (2)
To enable your repository manager to use the standard ACL security mechanism, you simply have to adopt some coding parts in your different aspects. The security checks are relevant for all aspects and have to be handled in each aspect's implementation separately. A single security check should be done before the method is executed. The security check can be executed through the
2006/Q2
© 2006 SAP AG. All rights reserved.
119
Unit 5: Repository Managers
EP130
SecurityChecker class, which encapsulates all standard security checks for the aspects. The following list shows which security check method has to be called in which aspects methods. Using security mechanisms: Important security checks
120
SecurityChecker method
Unified ascpect
Where to implement?
checkReadProperties(IResourceHandle)
Namespace
getCollectionOrderMechanism()
Namespace
getLinkDescriptor()
Property
getProperty()
Property
getProperties()
Property
getListedProperties()
Property
getAllProperties()
checkReadContent(IResourceHandle)
Content
getContent()
checkListChildren(IResourceHandle)
Namespace
findResources()
checkCreateChild(IResourceHandle)
Namespace
createResource()
Namespace
copyResource() [only destination collection]
Namespace
moveResource() [only destination collection]
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Security Checker
Exercise 6: Mandatory Aspects, Mutable Extensions, and the Security Checker Exercise Objectives After completing this exercise, you will be able to: • Implement mandatory aspects and mutable extensions and use the security checker in a basic repository manager
Business Example These skills are required for implementing a repository manager in most real-world situations. This is relevant for integration of back-end systems into the SAP NetWeaver KMC framework if no repository manager exists for the back end.
Task: Please follow the TODO tags in the projects for this Unit.
2006/Q2
© 2006 SAP AG. All rights reserved.
121
Unit 5: Repository Managers
EP130
Solution 6: Mandatory Aspects, Mutable Extensions, and the Security Checker Task: Please follow the TODO tags in the projects for this Unit.
122
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Security Checker
Lesson Summary You should now be able to: • Explain what the security checker is for • Use the security checker in your own code
2006/Q2
© 2006 SAP AG. All rights reserved.
123
Unit Summary
EP130
Unit Summary You should now be able to: • Explain how repository managers are integrated into the repository framework • List the components of a repository manager • Explain how the development tools support creation of repository managers • Explain the basics of implementing core repository manager functionality • Describe how aspects (feature sets) are implemented • Define a mutable extension • Implement a mutable aspect • Explain what the security checker is for • Use the security checker in your own code
124
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 6 KM Services Unit Overview KM services play a central role in extending the standard functionality of KMC. Generic global services and repository services are covered, as well as the Reporting API and the Application Properties service, which are both implemented as services in KMC. Finally, we will discuss the publishing pipeline, which is used to transform content to various formats on demand.
Unit Objectives After completing this unit, you will be able to: • • • • • • •
Explain the purpose of KM services Implement KM services Implement a custom report Explain the Application Properties Service API Store and retrieve properties using the API Store and retrieve user-specific properties using the API Explain how the publishing pipeline renders content
Unit Contents Lesson: KM Services Overview...............................................126 Lesson: Reporting ..............................................................134 Lesson: Application Properties Service ......................................144 Lesson: Publishing Pipeline ...................................................149 Exercise 7: Combining the Reporting API and Application Properties Service for Usage Statistics ...............................................155
2006/Q2
© 2006 SAP AG. All rights reserved.
125
Unit 6: KM Services
EP130
Lesson: KM Services Overview Lesson Overview This lesson covers repository and global services, which are main integration points for adding functionality to the standard delivery of the portal. Along with repository filters, services provide the most powerful and flexible method of implementing new functionality in KM.
Lesson Objectives After completing this lesson, you will be able to: • •
Explain the purpose of KM services Implement KM services
Business Example Your employer has asked you to develop a component that records statistics for documents and allows content managers to see what documents in the repository are most popular. You decide that the best way to gather these statistics is to implement a repository service that registers itself as a listener for document “GET” events.
KM Services Overview Repository services and global services play a central role in the KMC standard delivery. Many of the standard features in KMC are implemented as services. For example, the accessstatistic service is a repository service that is registered on repositories in order to record statistics on document access activities. This service records the time of last access by each individual user for each document in the repository on which it is registered. Note that it does not record the number of times a document is accessed. The scheduler service is a global service that provides cron-like functionality for KMC. This component is independent of any repository and allows the scheduled execution of custom code. It is also responsible for executing predelivered components of KMC at scheduled intervals in order to perform maintenance tasks. Beyond the services in the standard delivery of KMC, an API is provided to allow the implementation of custom global or repository services.
Repository Services Repository services are assigned to individual repositories for execution. A single service may be assigned to more than one repository. In general, the purpose of a repository service is to listen for and react to events that take place on a
126
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: KM Services Overview
repository. The service does this by registering itself as an event receiver with the repository manager's event broker. The registration specifies whether synchronous or asynchronous events are to be received and processed. The API for repository services is in the com.sapportals.wcm.repository.service package. Running the wizard for repository services outputs a code skeleton that looks similar to the following code sample.
public class MyRepositoryService extends AbstractRepositoryService implements IReconfigurable, IResourceEventReceiver { private static final String TYPE = "MyRepositoryService"; public MyRepositoryService() { super(); } public String getServiceType() { return MyRepositoryService.TYPE; }
protected void startUpImpl(Collection repositoryManagers) throws ConfigurationException, StartupException { } protected void shutDownImpl() { }
protected void addRepositoryAssignment(IRepositoryManager mgr) throws ServiceNotAvailableException { // Implement this method: Usually the service registers itself // for certain events at the repository manager. } protected void removeRepositoryAssignment(IRepositoryManager mgr) throws WcmException { // Implement this method: Usually the service must unregister // itself as an event handler.
2006/Q2
© 2006 SAP AG. All rights reserved.
127
Unit 6: KM Services
EP130
}
public void reconfigure(IConfiguration config) throws ConfigurationException { this.stateHandler.preReconfigure(); this.config = config; this.stateHandler.postReconfigure(); } public void received(IEvent event) { } }
This is the core of a repository service, contained in a single class that implements the IRepositoryService interface. This is generally done by extending the AbstractRepositoryService class. The TYPE static member variable is a unique identifier that identifies the repository service. Initialization of the service is done in the startUpImpl() method. This is where the service registers itself with the repository managers to which it has been assigned. The following code sample shows how a repository service would register itself to receive “GET” events on resources in the repositories to which it is assigned. These events are triggered when a document is retrieved from the repository.
protected void startUpImpl(Collection repositoryManagers) throws ConfigurationException, StartupException { try { for (Iterator i = repositoryManagers.iterator(); i.hasNext();) { addRepositoryAssignment( (IRepositoryManager) i.next() ); } } catch (Exception e) { throw new StartupException(e.getMessage(), e); } } protected void addRepositoryAssignment(IRepositoryManager mgr) throws ServiceNotAvailableException {
128
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: KM Services Overview
try { IResourceEventBroker b = mgr.getEventBroker(); b.register(this, ResourceEvent.GET_TEMPLATE, 0, true); } catch (WcmException e) { throw new ServiceNotAvailableException(e.getMessage()); } }
The logic is split between the startUpImpl() method and the addRepositoryAssignment() method. The startUpImpl() method is called when a new service instance is instantiated by the framework. At this time, the service is responsible for registering itself with the repositories to which it's assigned. It is also possible that repositories are assigned to an already instantiated repository service, which is handled by the addRepositoryAssignment() method. This occurs when an administrative user adds the service to a repository using the configuration UI for KMC. In this code example, the repository service retrieves the event broker for the repository manager in question and registers itself as a listener. Notice that the service must implement the IResourceEventReceiver interface in order to be able to receive these events. The call to register() on the event broker includes information about the type of events that are to be processed, in this case ResourceEvent.GET_TEMPLATE (this is a template object for the “GET” event). Other types of events that can be processed are also represented as template objects in the ResourceEvent class. These include property retrieval, saving of properties, saving of content, check-in and check-out events, among others. A list of basic events that can be processed can be found by reading the JavaDocs for the com.sapportals.wcm.repository.manager.ResourceEvent class. Besides the event type, the service also specifies it's priority as a listener in the broker's queue. This is the integer argument that is passed to the register() method. Lower values are higher priority. Event receivers (services in this case) that are registered for the same type as another receiver but with a lower priority will receive the event first. The final argument to register() denotes that asynchronous processing is to occur. This means that the receiver will receive the event notification at some point after the occurrence of the event with no opportunity to block. If a receiver registers itself as a synchronous listener, the action taken in the repository that triggered the event will not succeed until the event has successfully been processed. This way, actions can be blocked until certain prerequisite requirements have been validated. This makes sense in a limited number of scenarios and should only be used when synchronous processing is explicitly required for blocking purposes. It is very important that the service also unregister itself from the event broker of the repository manager when requested, as in the following code sample.
2006/Q2
© 2006 SAP AG. All rights reserved.
129
Unit 6: KM Services
EP130
protected void removeRepositoryAssignment(IRepositoryManager mgr) throws WcmException { IResourceEventBroker b = mgr.getEventBroker(); b.unregister(this, ResourceEvent.GET_TEMPLATE ); }
The processing of the event occurs in the received() method of the service. The following code sample illustrates basic processing of an event by checking if the event is an IResourceEvent and then retrieving the payload (an IResource object) for processing.
public void received(IEvent event) { if( event instanceof IResourceEvent ) { IResourceEvent re = (IResourceEvent) event; IResource r = re.getResource(); } }
Finally, the implementation of the IReconfigurable interface is not mandatory, but is supported and allows the repository service to be notified when the configuration of the service changes. This is true for many KMC components if they implement the IReconfigurable interface, they will receive notification of changes to the configuration when they are made in the user interface for KM administration by an administrative user. The instance of the service can be retrieved programmatically for direct interaction with the service object using the ResourceFactory, which gives access to repository services.
ResourceFactory.getInstance().getServiceFactory().getRepositoryService( theRepositoryManager, MyRepositoryService.TYPE );
Global Services A global service is independent of any particular repository. Our above example of a global service in the standard delivery is the scheduler service. This illustrates why global services must be independent of a repository: scheduled services need to execute independently of the status of any particular repository, since they are system-wide.
130
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: KM Services Overview
Because of this, global services are somewhat easier to implement than repository services. They do not register as listeners on a repository. Programmatic interaction with the service is attained by using the ServiceFactory to look up an instance of the service that is registered using a KEY similar to the repository service.
ServiceFactory.getInstance().getService( KEY );
After running the wizard for global services, the generated code is simlar to the code sample below. This code sample omits the implementation of the IReconfigurable interface for brevity, but the principle here is the same as for repository services.
public class MyGlobalService extends AbstractService implements IThreadSafe { private static final String TYPE = "MyGlobalService";
public MyGlobalService() { super(); } public String getType() { return MyGlobalService.TYPE; } protected void startUpImpl() throws StartupException, ConfigurationException { }
protected void shutDownImpl() { } public String getDescription() { return ""; }
public String getDescription(Locale parm1) {
2006/Q2
© 2006 SAP AG. All rights reserved.
131
Unit 6: KM Services
EP130
return ""; } }
Notice that there is no received() method, since this service is not responsible for processing events. Additionally, global services have a pair of getDescription() methods that provide a description to the user interface for administrative users.
132
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: KM Services Overview
Lesson Summary You should now be able to: • Explain the purpose of KM services • Implement KM services
2006/Q2
© 2006 SAP AG. All rights reserved.
133
Unit 6: KM Services
EP130
Lesson: Reporting Lesson Overview This lesson introduces the KM Reporting service and its API, along with some of the reports in the standard delivery and the specifics of implementing a custom report. Commands are simple logic that can be executed on single resources during a report run.
Lesson Objectives After completing this lesson, you will be able to: •
Implement a custom report
Business Example You have been asked to develop a report on what documents in the portal receive the most hits. You decide that the best and easiest way to do this is to use the KM reporting API.
The Reporting Service The KM Reporting service is a global service with its own repository manager implementation for persistence. A standard set of standard reports is delivered that can be used immediately. In addition to the standard reports, the KM Reporting API is accessible for custom development and allow you to extend the reporting service with custom reports. The Reporting service collects data from KM resource objects and presents them in a standard format. The type of data that is gathered and reported on is dependent on the report that is being run. Any data that is accessible via the KM API can be used for reporting purposes. The scope of a report (which resource trees it applies to) can be defined at runtime, as can other custom parameters. Commands or actions to be taken on single resources can also optionally be executed on resources during the reporting run.
134
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Reporting
Report output or results are stored as XML resources in the reporting repository in KM and can be accessed like any other resource. A standard or custom stylesheet can be applied to the output for viewing. The standard rendering of reporting output utilizes KM's flexible user interface. •
Additional service for KM
•
– Schedules and executes reports based on KM information Delivers a set of standard reports –
•
Resource Lock report: Reports on resources that are locked; optionally, can remove locks on resources found – ACL Permissions: Lists the ACL-based permissions of users for documents – User Resources: Finds all items related to a certain user Reports are presented with KM flexible UI components
•
– Report overview – Report results Repositories are used for persistence – –
Service uses its own repository manager implementation for reports Reports are assigned to a special repository manager instance
The Reporting API
Figure 61: Reporting API
2006/Q2
© 2006 SAP AG. All rights reserved.
135
Unit 6: KM Services
EP130
Figure 62: Components of Reporting API
IReport is the main interface when implementing a custom report and must be implemented in order to give the Reporting service an entry point into the custom report. Other interfaces should not be implemented, but used directly (that is, objects implementing these interfaces will be provided by the framework runtime). IReport parameters IReport parameters com.sapportals.wcm.service.reporting
136
IReport
Main report object. Interface to reporting service. execute() is main method.
IReportInput
Input parameters. Contains commands, max results, scope, and programmer-defined parameters.
IReportInputError
Main interface used to report errors in report execution.
IResultItem
Represents a single result item in a report result. Created using ResultItem.getInstance().
IReportCommand
Represents a command that can be executed on results of the report.
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Reporting
Figure 63: Reporting API
A set of custom input parameters may be defined at design time. The reporting framework will use these parameters to gather user input when a report is run. For example, the standard-delivered report “Resource Statistics” defines a number of custom parameters to limit the result set. This report can be configured to check on resources created by a specific user, among other things. The following piece of code illustrates how parameters are defined within a custom report.
2006/Q2
© 2006 SAP AG. All rights reserved.
137
Unit 6: KM Services
EP130
Figure 64: Defining Custom Parameters for a Report
The reporting framework and GUI support the verification of report input. This verification consists of a button in the GUI that the user can press to verify the input he or she has provided, as well as custom code that is executed when the button is pressed. The code sample below gives an example of what the verification process might look like.
Figure 65: Verifying Parameter Input
138
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Reporting
The execute method is the core of the custom report's logic and is called when the report is run, either manually or during a scheduled run. This method generally performs recursive processing on the resources that are given as the scope of the report. The code sample in the figure below shows a very basic mode of execution. For the sake of simplicity, the sample code does not include any recursive processing. When recursive processing is necessary, it is important to keep in mind that there is a set of classes to handle the recursion logic properly. It is not difficult to implement the recursion manually, but it is easy to make simple mistakes that have dire consequences on system performance. Therefore, it is highly recommended that you make use of the provided classes. Note: The classes that handle recursive processing are in the com.sapportals.wcm.service.reporting.walker package.
Figure 66: The execute() Method
During the report run, a result set of KM object information is maintained, which is returned to the framework for persistence and later display.
2006/Q2
© 2006 SAP AG. All rights reserved.
139
Unit 6: KM Services
EP130
Figure 67: The ResultSet Object
Commands provide a method of executing arbitrary logic on KM resources encountered during a reporting run, and can optionally be included in a report implementation. The code below shows an implementation of a command used to delete individual resources. This might be used, for instance, in a report that checks to see whether a repository hierarchy contains dead links, that is, links that have a nonexistent target resource. The user running the report could then opt to execute this command on the resources found to remove dead links from the system.
140
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Reporting
Figure 68: Using Commands in Reports
Figure 69: Executing Commands on Report Results
2006/Q2
© 2006 SAP AG. All rights reserved.
141
Unit 6: KM Services
EP130
Useful additional methods: •
IResultReceiver.addError(…)
•
– Adds an erroneous item to the result IResultReceiver.investigate(…)
•
– Tracks the state of the current report IReportInput.getCommandInput(…) –
•
Retrieves the input for commands from the UI if they are supported by the report implementation IReportInput.setMaxResults(…) –
Sets the limit of maximum results processed by this report implementation
Configuring Reports After deployment, every IReport implementation must be registered in the KM configuration at Content Management → Repository Managers → Reports.
Figure 70: Configuration of Reports
142
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Reporting
Lesson Summary You should now be able to: • Implement a custom report
2006/Q2
© 2006 SAP AG. All rights reserved.
143
Unit 6: KM Services
EP130
Lesson: Application Properties Service Lesson Overview This lesson covers the Application Properties Service. This API allows the storage and retrieval of properties independently of any specific repository. The storage and retrieval of user-specific properties are also covered.
Lesson Objectives After completing this lesson, you will be able to: • • •
Explain the Application Properties Service API Store and retrieve properties using the API Store and retrieve user-specific properties using the API
Business Example You have been asked to add “tags” as a feature to your corporate KM installation. These tags will allow users to mark documents with keywords of their own choice, as well as to browse the tags that others have chosen for documents. You decide that you need the ability to store these tags on the individual documents, and also the ability to quickly query for all documents with a given tag. Application properties are best suited for this purpose.
The Application Properties Service The purpose of this service is to persist properties of resources in the KM database, independent of a specific repository. As of SAP NetWeaver 04, Support Package 13, this service is available as a global service. It is contained in the JAR file com.sap.netweaver.bc.rf.service.jar. The application properties service can be used by any KM or portal component in the system to persist arbitrary data in the database using a resource identifier (RID) as the key (unique identifier). The service uses the notion of a “property” for the data, which is very similar to the one used by the repository framework. A property consists of a name and a data type and can have a value or a list of values. The IAppProperty interface defines a property of this type, which you can store and retrieve using the methods in IApplicationPropertiesService. Why was such a service developed when the repository framework already offers resource properties? First, the application properties are independent of a repository. A certain repository might have special restrictions for the property names or values – or it might not support properties at all (for example, the file system repository). Second, the service offers features that are not available for resource properties.
144
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Application Properties Service
The API provides a method to store, retrieve, and remove properties, and a method to search for RIDs using property values as search criteria. The service supports user-specific properties. In the Javadoc, the term “personalized property” is used. This means that a property of this type is associated with a user name (more precisely, the unique identifier of a user as defined by the User Management Engine [UME]), which has to be given as an argument when the property is created. The API also provides methods to retrieve or delete all properties associated with a particular user ID. The Application Properties service can be characterized as a persistency for simple objects such as integers, dates, and strings using the RID, property name, and user ID as keys. The service has a few more useful features because it is also integrated in the repository framework as an event receiver. This means it handles the Delete, Rename/Move, and Copy events that are created by the repository framework for all repository operations. If a resource is deleted, the service removes all the properties from the database. Rename and move operations are handled in such a way that all properties are related to the new RID. If a resource is copied, you can choose whether all properties are also copied. You must make that choice when creating a property. Finally, it should be emphasized that application properties are not resource properties – neither at the API level (they are accessed using a different interface) nor at the user interface level. This means they cannot be retrieved using the IResource.getProperty/getProperties methods and therefore do not show up on the KM user interface. Interfaces and their purpose Interfaces and their purpose Interface
Purpose
ApplicationPropertiesService (NetWeaver 04)
The main service interface
ApplicationProperties (KM 6.0) IAppProperty, AppProperty
Defines the property data: name, data type, value(s), and copy flag
IAppPropertyCollection, IAppPropertyIterator, IAppPropertyMap, IResourceAppPropertyMap
Returned by the various methods in IApplicationPropertiesService that retrieve properties
The following code sample shows how to get the service and how application properties are stored on a resource.
2006/Q2
© 2006 SAP AG. All rights reserved.
145
Unit 6: KM Services
EP130
// Get a reference to the service from the RF IApplicationPropertiesService apService = (IApplicationPropertiesService)ResourceFactory.getInstance(). getServiceFactory(). getService(IApplicationPropertiesService.SERVICE_ID); // This is the resource we are going the associate the property // with IResource resource = ...
// Create the property object.IPropertyName name = new PropertyName("test", "test"); IAppProperty prop = new AppProperty(name, "value", null, false);
// Set property – an existing property with the same RID and name // will be overwritten. apService.setProperty(prop, resource);
Please note: • • •
The Application Properties service has to be retrieved from the ResourceFactory instance. The resource with which the property is associated must be retrieved from a KM repository. The property itself is built up with a namespace and a property name.
The following code sample shows how application properties are retrieved from a resource.
IAppProperty prop = apService.getProperty(name, resource); if (prop != null { prop.getStringValue(); }
IAppPropertyMap properties = apService.getProperties(resource);
User-specific properties can also be created and stored. This is not supported by the resource properties provided by the repository framework. To create a user-specific property, the third argument of the constructor must specify the user ID. This should be the unique ID of the IPrincipal object in the UME.
// creation IAppProperty prop = new AppProperty(name, "value", principal.getUniqueID(), false);
146
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Application Properties Service
// deletion IAppProperty prop = apService.getProperty(name, resource, principal.getUniqueID());
A second distinguishing feature of application properties is search capability. The API offers a method to search for resources (RIDs) using property values as search criteria. Note that the result might contain resources in many repositories. You cannot restrict the results to a single repository. The RIDs in the result list are guaranteed to be unique (no duplicates). In the following code example, a search is executed for all resources that contain a user-specific property where the Boolean value equals “true.”
IPropertyName name = new PropertyName("test", "test"); String userID = principal.getUniqueID(); IRidList result = apService.search(name, userID, Boolean.TRUE, Operator.EQUAL); if (result.size() > 0) { IResourceList rl = ResourceFactory.getInstance(). getResources(result, context); ... }
2006/Q2
© 2006 SAP AG. All rights reserved.
147
Unit 6: KM Services
EP130
Lesson Summary You should now be able to: • Explain the Application Properties Service API • Store and retrieve properties using the API • Store and retrieve user-specific properties using the API
148
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Publishing Pipeline
Lesson: Publishing Pipeline Lesson Overview The publishing pipeline and XSLT pipeline services transform resources from one format to another or from one layout to another. The XSLT pipeline is a specialized version of the pipeline for the transformation of XSLT. It is used by repository filters and by the XML Forms Builder for forms-based publishing.
Lesson Objectives After completing this lesson, you will be able to: •
Explain how the publishing pipeline renders content
Business Example The Publishing Pipeline The publishing pipeline is the technical infrastructure that enables the transformation of resources from one format to another or from one layout to another. When a filter has been defined for a particular file extension, mime type or folder, it is the pipeline that actually executes the transformation process specified by the filter. The pipeline package and other related packages offer interfaces that can be addressed by an application that wants to use the pipeline. Before introducing these interfaces, the following section gives you an overview of the architecture of the pipeline and explains how the pipeline works at a technical level. This background information makes it easier to understand the purpose of the interfaces in this package and the other related packages. The pipeline is composed of three main components: the producer, the processor and the formatter. Each of these is responsible for executing a different part of the process that transforms a file from one form to another. The components are bound together by a supervisory instance, the pipeline controller, which coordinates and controls the work of the other components.
Figure 71: Pipeline Architecture
2006/Q2
© 2006 SAP AG. All rights reserved.
149
Unit 6: KM Services
EP130
The producer is the first instance that is called, when there is a request to process a resource with the publishing pipeline. It fetches the content of the resource, prepares it for further processing and passes it on to the processor. The processor then carries out the actual transformation process and changes the layout or format of the resource. Finally, the formatter prepares the output. It processes the resource with a formatter program to generate output with a particular format or it simply prepares an output stream and passes it on to another instance. Depending on whether the resource that is processed is an XML or non-XML file, the individual steps within the process differ. The next section explains the individual processing steps of the publishing pipeline in detail, taking into account the different approaches that are necessary for XML and non-XML resources. The pipeline controller is an internal component that is responsible for ensuring that the processing steps executed by the pipeline are performed by the right component in the right sequence. To do this, the controller needs instructions encoded in XML. If the resource that is processed by the pipeline is already an XML resource, the instructions can be included directly in this file. If the resource has a different format, an additional empty XML is required to store them. The manner in which the controller is supplied with instructions can differ. The instructions may already be included directly in the resource that is passed on to the pipeline, or they may be provided by parameters of method calls. In rare cases they have to be fetched from other sources and subsequently written into the XML file. The pipeline offers a default processor that acquires the processing information for the Controller and writes it into the available XML file. Whenever the controller registers that no instructions are available, it starts the default processor and is therefore able to obtain the relevant processing information. Typically, the instructions for the controller specify the type of pipeline processor that is required, the URL of the stylesheet that is to be applied to the document and the formatter program that generates the output. The example here shows instructions that inform the controller to start an XSLT processor, to use the stylesheet page.xsl and to run the formatter program that generates HTML.
< ?wcm-process type="xslt"? > < ?xml-stylesheet href="page.xsl" type="text/xsl?" > < ?wcm-format type="text/html"? >
The default processor provides methods for controlling the processing from your custom code:
class DefaultProcessor implements IProcessor { void addWcmProcess(int step, String name); void addWcmFormat(String name);
150
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Publishing Pipeline
void addProcessingInstruction( int step, String target, String href, String type); }
The main components of the publishing pipeline, along with their functions, are: •
Producer –
•
Reads data from a data source (IResource, InputStream, URL, and so on) – Provides a RequestData object containing an XML DOM object if input is XML. If input is non-XML, the producer provides a stream to the data. Processor
•
– Processes the incoming RequestData and transforms it – Provides RequestData object with transformed result Formatter
•
– Creates (non-XML) viewing format from RequestData – Provides IContent object with formatted result – StreamFormatter for available non-XML data Controller – – –
Responsible for ensuring that the processing steps executed by the pipeline are performed by the correct component in the correct sequence Calls processors and formatter Information relevant to the controller (formater, processor) based on XML processing instructions passed to controller
The Publishing Pipeline In Practice Most transformations performed with the pipeline use the XSLT processor to convert an XML file with an XSL stylesheet. For these transformations, it is easiest to use the IXsltPipelineService interface because it is specialized for this process and automates some of the steps.
// package com.sapportals.wcm.service.pipeline interface IXsltPipelineService { // Methods to invoke pipeline transformation
2006/Q2
IContent
handle(InputStream xml, InputStream xsl, Hashtable properties) ;
IContent
handle(InputStream xml, InputStream xsl, Hashtable properties, String mime);
IContent
handle(IProducer xml, IProducer xsl, Hashtable properties);
© 2006 SAP AG. All rights reserved.
151
Unit 6: KM Services
EP130
IContent
handle(IProducer xml, IProducer xsl, Hashtable properties, String mime) ;
IContent
handle(IProducer xml, String xslUrl, Hashtable properties) ;
IContent
handle(IProducer xml, String xslUrl, Hashtable properties, String mime) ;
IContent
handle(String xmlUrl, String xslUrl, Hashtable properties) ;
IContent
handle(String xmlUrl, String xslUrl, Hashtable properties, String mime) ;
} interface IProducer { RequestData getData(); Date
getLastModified() ;
String getPath(); }
interface IProcessor { RequestData
process( RequestData data, Dictionary parameters ) ;
} class RequestData { Document getDocument(); InputStream getStream(); // ... etc }
The following code sample shows how to use the pipeline service to perform a simple transformation operation on an XML document using an XSL stylesheet.
// get the XML file from the user input - variable xmldoc FileInputStream xmlInput = new FileInputStream(xmldoc); // get the XSL file from the user input - variable xsldoc FileInputStream xslInput = new FileInputStream(xsldoc); // create a new resource with the xml file xmlResource = aCollection.createResource(xmlname, null, aContent); // create a new resource with the xsl file xslResource = aCollection.createResource(xslname, null, aContent); // get the pipeline service IXsltPipelineService xsltpl = (IXsltPipelineService) ServiceFactory.getInstance().getService(IServiceTypesConst.XSLT_PIPELINE_SERVICE);
152
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Publishing Pipeline
// create ProducerFromResource object for the xml and xsl resource ProducerFromResource xmlFile = new ProducerFromResource(xmlResource); ProducerFromResource xslFile = new ProducerFromResource(xslResource);
// run the pipeline IContent content = xsltpl.handle(xmlFile, xslFile, null);
Figure 72: Publishing Pipeline Example: XML Content Before Transformation
Figure 73: Publishing Pipeline Example: PDF Output of Transformation
2006/Q2
© 2006 SAP AG. All rights reserved.
153
Unit 6: KM Services
154
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Publishing Pipeline
Exercise 7: Combining the Reporting API and Application Properties Service for Usage Statistics Exercise Objectives After completing this exercise, you will be able to: • Combine the Reporting API and Application Properties service to implement an application to track usage statistics in KM
Business Example A customer would like to know which documents accessible to users in KM are the most popular.
Task: This exercise consists of two functional units. The first is a repository service that gathers usage statistics for documents in KM. It does this by listening for the “GET” event. Every GET event for a document is recorded as a hit on that document by storing and incrementing a counter. The counter is stored as an application property associated with the resource in question. The second functional unit for this exercise is a report that evaluates and presents the information stored on the resources. 1.
2006/Q2
Please implement the task steps marked “TODO” in the project delivered with this unit.
© 2006 SAP AG. All rights reserved.
155
Unit 6: KM Services
EP130
Solution 7: Combining the Reporting API and Application Properties Service for Usage Statistics Task: This exercise consists of two functional units. The first is a repository service that gathers usage statistics for documents in KM. It does this by listening for the “GET” event. Every GET event for a document is recorded as a hit on that document by storing and incrementing a counter. The counter is stored as an application property associated with the resource in question. The second functional unit for this exercise is a report that evaluates and presents the information stored on the resources. 1.
Please implement the task steps marked “TODO” in the project delivered with this unit. a)
156
–
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Publishing Pipeline
Lesson Summary You should now be able to: • Explain how the publishing pipeline renders content
2006/Q2
© 2006 SAP AG. All rights reserved.
157
Unit Summary
EP130
Unit Summary You should now be able to: • Explain the purpose of KM services • Implement KM services • Implement a custom report • Explain the Application Properties Service API • Store and retrieve properties using the API • Store and retrieve user-specific properties using the API • Explain how the publishing pipeline renders content
158
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 7 Flexible UI Unit Overview The flexible UI is responsible for rendering the KM navigation hierarchy and metadata for end users of the portal. It is customizable through configuration as well as extension by using the Flex UI API. This unit will help you identify what components are available through the Flex UI API and how you can use them to implement custom rendering.
Unit Objectives After completing this unit, you will be able to: • • • • •
Build custom UI elements and layouts using the flexible UI API List which components of the flexible UI API are customizable via coding List which components of the Flex UI are customizable Describe what each Flex UI component is used for Use the built-in facilities to debug flexible UI presentations
Unit Contents Lesson: Architecture............................................................160 Lesson: Components...........................................................168 Lesson: Debugging .............................................................189 Exercise 8: Flexible UI .....................................................193
2006/Q2
© 2006 SAP AG. All rights reserved.
159
Unit 7: Flexible UI
EP130
Lesson: Architecture Lesson Overview You can extend the KM flexible user interface using your own Java classes. You do not need to rebuild the flexible user interface from scratch if you want to implement extensions for special purposes. Instead, you can write the extensions that you need, and you can reuse elements delivered by SAP. You write your extensions in your own Java classes, without modifying the Java classes delivered by SAP. You can use the configuration to integrate your Java classes into the user interface. This procedure has the advantage that your extensions are retained when you upgrade to a higher release.
Lesson Objectives After completing this lesson, you will be able to: • •
Build custom UI elements and layouts using the flexible UI API List which components of the flexible UI API are customizable via coding
Business Example Your project has asked you to design a new user interface for corporate end-users of the portal. These users are not power users, so they require a simple interface with a restricted set of features and functions that can be performed on documents. You design the new interface based on the functionality available to you via the Flexible User Interface.
The Flexible UI “Flexible UI” or “Flex UI” refers to the ability to customize the KM user interface through configuration and coding. The KM Navigation iView, the search results and the Details screen for resources can all be customized using the techniques discussed here. Each user accessing KM via the KM Navigation iView can be presented with a different layout based on his or her role. For instance, the following diagram shows a layout typically used by administrators, along with a layout used to render news items in KM. These two examples show what can be done using the Flexible UI and making only configuration changes - no custom coding was required for either of these layouts.
160
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Architecture
Figure 74: Flexible UI: Examples
These configuration changes used to create the layouts illustrated above can be made on a running system and are effective immediately. In addition to a configurable user interface, Flex UI allows for the creation of custom components in Java to allow developers to extend the existing functionality. The Flex UI follows a component model of resource, collection and property renderers (as well as other components), which allows for this extensibility through programming. To simplify development work, the Flex UI offers predefined components called ready-mades, which you can integrate in collection, resource, and property renderers. Although the Flexible UI is not designed for the creation and adaptation of screen flows, you can use it to include confirmation screens for actions associated with ICommand or IMassCommand objects. This so-called one-step screen flow is only suitable for a limited adaptation of the screen flow. The Knowledge Management application provides a number of renderer packages that allow a highly flexible representation of explorer controls. The explorer controls enable the user to navigate through repositories and perform basic operations on resources. They are the main point of access to the KM repositories and therefore play a central role in the application. For this reason, it is essential that they can be customized and adapted in different ways to meet the requirements of different types of users. This flexibility is achieved with the functions of the renderer and layout service packages, which make it possible to adapt the controls in appearance, behavior, and complexity to suit different individuals or groups. For example, an administrator can be presented with a complex browse control that provides meta-information about resources and mass actions. A casual user can be presented with a simple control that has an attractive appearance,
2006/Q2
© 2006 SAP AG. All rights reserved.
161
Unit 7: Flexible UI
EP130
a few essential commands, and an easy intuitive form of navigation. Usability and system performance are both affected by Flexible UI configuration, so it is important to understand what options are available. The following two screenshots show what components in the search results set and the Details dialog are configurable or otherwise cusomizable using the Flex UI.
Figure 75: Flexible UI: KM Navigation and Search Results iViews
Figure 76: Flexible UI: Details Dialog Screen
162
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Architecture
The following is a diagram of the components used when rendering pages for KM. Please use this as a reference as each of these components is discussed and as you work with your KM installation. The center block in the diagram represents the core of the classes that can be customized through coding: collection, resource and property renderers, as well as commands and layout controllers.
Figure 77: Flexible UI: Architecture
2006/Q2
© 2006 SAP AG. All rights reserved.
163
Unit 7: Flexible UI
EP130
Flexible UI Component Types: Overview The main points of customization through coding are layout controllers and the objects that they arrange on a page: collection, resource and property renderers. In addition to these, KM also allows the development of custom commands, which allows for the execution of arbitrary code on individual resource or a set of resources. •
Controller and renderer – – – – –
•
Layout controller: Determines layout of objects on screen Collection renderer: Called to render collections (lists of resources) Resource renderer: Called to render individual resources Property renderer: Called to render properties of individual resources Breadcrumb renderer: Called to renderer breadcrumb (navigation path) for current location within the KM folders Commands – – – –
Commands allow execution of arbitrary (custom or predelivered) code on resources or sets of resources Examples: Copy, move, delete, send to, check in, check out External UI command UI command with screen flow
The following screenshot shows how these individual components are arranged on a rendered page by the layout controller. The layout controller is the outermost component and is responsible for breaking the screen down into its subcomponents and calling the appropriate renderer for each area of the screen. The “flavor” of a component determines which exact renderer is used at run time. This provides the Flex UI with a loose coupling system and enables collection and resource renderers (and breadcrumb) renderers to be associated with a layout controller at configuration time.
164
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Architecture
Figure 78: Components of Flexible UI
A layout controller will specify only flavors of renderers, such as “Grid” or “List” in code. The administrator responsible for configuring the layout set containing the layout controller then associates a renderer of the same type with the layout set. For instance, a layout controller might specify that an area of the screen be rendered as a “List” by using the identifier for that flavor in the source code. During configuration, this layout controller is used in a layout set that also contains a collection renderer with flavor “List”. At runtime, the calling framework is able to match the individual renderers with their respective screen blocks based on these flavors. The flavors are meant to represent different styles of rendering, so a “List” layout controller would render a set of resources as shown in the above screen. Other examples of flavors are “Grid” (also shown above) and “Tree”. In addition to these renderers, property renderers are required to render the individual property values for resources (both collections and leaf resources). A good example for the necessity of property renderers is the “rating” property, which is rendered as a set of colored boxes representing the value of the rating. Custom properties used by customers may also require custom rendering. Finally, UI commands are displayed on the screen. In the example above, the individual commands are not shown, but are contained in drop-down menus to the right of each resource's displayed name. The diagram below shows the call stack for rendering operations and also introduces the parameterization of each of the components. The diagram indicates that there are five sources from which a renderer or controller can take settings:
2006/Q2
© 2006 SAP AG. All rights reserved.
165
Unit 7: Flexible UI
EP130
default hard-coded values, global settings, folder settings, URL parameters and OTH (object type handler) files. These are in order of reverse priority - if an OTH value is present, that is taken, and so on.
Figure 79: Flexible UI Call Stack and Settings
Hint: This is useful information when debugging Flex UI configurations, which is covered later in this unit.
166
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Architecture
Lesson Summary You should now be able to: • Build custom UI elements and layouts using the flexible UI API • List which components of the flexible UI API are customizable via coding
2006/Q2
© 2006 SAP AG. All rights reserved.
167
Unit 7: Flexible UI
EP130
Lesson: Components Lesson Overview The flexible UI provides several interfaces and abstract classes that can be used to build custom UI elements. Various renderer elements (property, resource, and collection) provide a method of controlling the detailed rendering of KM objects. This allows a high degree of control over the presentation of both structured and unstructured data.
Lesson Objectives After completing this lesson, you will be able to: • •
List which components of the Flex UI are customizable Describe what each Flex UI component is used for
Business Example Your project has asked you to develop a component that will allow a group of non-technical end users to see a subset of documents in the repository. You know that developing a repository filter is the wrong approach, since this will affect all users in the system. You decide the best way to implement your requirements is to develop a resource list filter.
Basics of Developing Custom Flex UI Components in Java Creating your own flexible UI components is useful when a highly customized rendering of KM content is required. The standard delivery of flexible UI components is large, but can not cover all conceivable layouts and rendering. If rendering is driven by corporate design guidelines, it is common to implement custom flexible UI components to meet these guidelines. The component API also allows for special rendering of custom properties not handled by the standard property renderers.
Tool Support Like other KMC components, Flex UI components are developed in the Enterprise Portal perspective in NetWeaver Developer Studio. However, there is no wizard support for flexible UI components. Instead, a workaround is possible by creating an empty repository framework project, such as a scheduler task or global service, and removing the generated code and configuration information. This leaves the developer with a proper project structure, including classpath and configuration information. In addition to this, all libraries with a name following the pattern km.shared.ui.flex.* as well as the htmlb.jar libary will need to be included in the project classpath.
168
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
The next step is to implement the flexible UI component by extending the corresponding abstract class and / or implementing required interfaces. These individual component types and their interfaces are discussed in more detail below. Finally, deployment of the component is the same as for other KMC projects.
Configuration The basic principles behind configuring a custom Flex UI component are the same as for other KMC components. The configuration object XML files (*.co.xml) are placed within the configuration structure under src.config/install/data/cm/ui. In general, this structure follows the structure found in the configuration UI in the portal, and this is true for Flex UI components as well.
Figure 80: Flexible UI Components: Configuration Structure
Since there is no wizard to generate configurable object and class information for Flex UI components, the following example has been included as a reference.
2006/Q2
© 2006 SAP AG. All rights reserved.
169
Unit 7: Flexible UI
EP130
Figure 81: Flexible UI Components: Configuration Information
Component Model in Detail The previous unit introduced the basic components available for customization through coding. This section covers each of these basic components in more detail.
Layout Controller The outermost component on a KM page is the layout controller. The layout controller decomposes the screen into subareas and hands the rendering of these subareas off to the appropriate renderers. It does this by assigning a flavor to each area of the screen. For each of these areas, the renderer that has been configured as a handler for a flavor is called during execution of the rendering. The layout controller does this by assigning com.sapportals.wcm.rendering.control.cm.NeutralControl objects to each subarea of the screen. Instead of this, other classes extending com.sapportals.wcm.control.base.WcmResourceControl may be used. These custom controls extending WcmResourceControl may optionally implement the following interfaces: • • •
170
IStartUriReceiver: Retrieve start path RID to determine the location ITypedResourceListControl: Retrieve a typed resource list. For example, from a search result list IMassCommandSupporter: Support mass commands for resource items.
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
The default constructor for custom controls is mandatory. Additional constructors used by the framework are: • •
public: CustomNeutralControl(IProxy proxy) public: CustomNeutralControl(IProxy proxy, String flavor)
The layout controller itself must extend the AbstractLayoutController class. The layout controller manages the instances of the neutral controls (or other WcmResourceControl objects) and renders an HTMLB component. It is important to understand that the layout that a layout controller determines is generally fixed, which means that a layout controller must be implemented for each desired component layout. The following code sample shows an example of a basic layout controller. Notice that instances of the layout controller are created by using the getNewInstance() method, which in turns calls the appropriate constructor. The core of the layout controller is in the render() method, which is called to perform the actual rendering. In this example, a simple grid of the controller's controls are rendered. Not shown in this code sample is the method createControls(), which instantiates the NeutralControl elements and assigns a flavor to each.
public class CustomLayoutController extends AbstractLayoutController { public ILayoutController getNewInstance() { return new CustomLayoutController(); } public Control[] getControls() { if (controls == null) controls = createControls(); return controls; } public Component render() throws WdfException { GridLayout result = new GridLayout(); result.setHeightPercentage(100); for (int i = 1; i < controls.length; i++) { int row = i / 4; int col = i % 4; GridLayout temp = new GridLayout(); temp.addComponent(1, 1, new Label(controls[i].getID())); temp.addComponent(1, 2, controls[i].render()); result.addComponent(row, col, temp); } result.setWidth("100%"); return result; } }
2006/Q2
© 2006 SAP AG. All rights reserved.
171
Unit 7: Flexible UI
EP130
Layout controller configuration information is contained in the ui/mapping section of the src.config tree within a project.
Collection Renderer The collection renderer manages the rendering of a single collection and its content. It is responsible for defining the layout and ordering of resources within a collection. It also filters resources by applying ResourceListFilters. Note that these filters (discussed below) are different than repository filters, covered in Unit 4. Two common flavors of collection renderers are Tree and List. These are illustrated by the screenshot below. The left-hand side of this screen shows a tree rendering of the “root” folder. The right-hand side of the screen shows the same folder rendered as a list, showing that the list rendering is suited for displaying more detailed information about resource. The tree rendering is well-suited to displaying hierarchies and allowing their navigation.
Figure 82: KM Navigation iView Showing Tree and List Renderings
There are two base classes that can be extended when implementing a collection renderer. com.sap.sen.wcms.flexui.renderer.LightCollectionRenderer is a lightweight implementation and is recommended for use as a base class for new implementations. The use of com.sapportals.wcm.rendering.collection.AbstractCollectionRenderer is no longer recommended, since it has been replaced by LightCollectionRenderer.
172
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
An implementation of a collection renderer must overwrite the getNewInstance() and renderUI() methods. The lifetime of a collection renderer is a single request cycle, and getNewInstance() is called once. Instances are initialized with their parameters from the configuration using the initNewInstance() method (please see source code example below). The renderUI() method must return a valid HTMLB component. This method is called by the framework to execute rendering. The following source code shows an example of these two methods.
public class CustomCollectionRenderer extends LightCollectionRenderer { public ILayoutObject getNewInstance() { return this.initNewInstance(new CustomCollectionRenderer()); }
public Component renderUI() throws WcmException { GridLayout grid = new GridLayout(); IResourceList iResList = this.getResourceList(); for(int i = 0; i < iResList.size(); i++){ int row = i/4; int col = i%4; IResource res = iResList.get(i); GridLayout temp = new GridLayout(); temp.addComponent(1,1, new Label("SimpleLabel")); temp.addComponent(1,2, this.getRenderer(res).renderIcon()); temp.addComponent(1,3, this.getRenderer(res).renderImage()); temp.addComponent(1,4, this.getRenderer(res).render()); grid.addComponent(row, col, temp); } return grid; } }
The following gives an example of the configuration information for a custom collection renderer.
2006/Q2
© 2006 SAP AG. All rights reserved.
173
Unit 7: Flexible UI
EP130
Figure 83: Flexible UI Components: Collection Renderer Configuration Code
Collection renderer instances for runtime are configured in the KM configuration UI. These will include a reference to the implementation (SimpleExampleCollectionRenderer in this example).
Figure 84: Flexible UI Components: Collection Renderer Settings in UI
174
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
Resource Renderer The resource renderer manages the rendering of a single resource and its metadata. It defines the layout and ordering of properties for a resource, but does not render those properties. The screenshot below shows an example of the results of a resource renderer rendering a search result.
Figure 85: Flexible UI Components: Resource Renderer
Resource renderer – Implementation: Implementing a resource renderer follows the same pattern as a collection renderer. The base class to be extended by new resource renderer implementations is com.sapportals.wcm.rendering.resource.AbstractResourceRenderer. The getNewInstance() and render() methods must be overridden. As is the case for collection renderers, the lifetime of a resource renderer is a single request cycle, and getNewInstance() called once during this cycle. No parameter initialization is possible for resource renderers. The render() method must return a valid HTMLB component. The deprecated renderIcon() and renderImage() methods may be delegated to the render() method.
public class CustomResourceRenderer extends AbstractResourceRenderer { public ILayoutObject getNewInstance() { return new CustomResourceRenderer(); }
public Component render() throws WcmException
2006/Q2
© 2006 SAP AG. All rights reserved.
175
Unit 7: Flexible UI
EP130
{ GridLayout result = new GridLayout(); result.addComponent( 1, 1, new Label(this.getResource().getDisplayName())); return result; } public Component render(IProperty prop) throws WcmException { return this.render(); }
public Component renderIcon() throws WcmException { return this.render(); } public Component renderImage() throws WcmException { return this.render(); } }
Configuration of the resource renderer is very similar to a collection renderer. The following two diagrams illustrate this and are meant as a reference.
176
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
Figure 86: Flexible UI Components: Resource Renderer Configurable Object
Figure 87: Flexible UI Components: Resource Renderer Instance
2006/Q2
© 2006 SAP AG. All rights reserved.
177
Unit 7: Flexible UI
EP130
Property Renderer Property renderer: • •
Manages the rendering of a single property of a resource Supports different types – –
Modeled property renderer for Navigation iViews Structured property renderer for Details and Upload iView –
Different modes
– Display – Edit – List Renderers must be linked with a valid property metadata definition
•
–
Property must be modeled (see Property Metadata service)
Property renderer – Implementation: •
Implements IModelledPropertyRenderer interface
•
– No abstract class provided (!) Implements the renderProperty() method – –
Property, property definition, and proxy information is passed in Returns a valid HTMLB component
public class CustomPropertyRenderer implements IModelledPropertyRenderer { public Component renderProperty(IProperty prop, IMetaName metaname, IResource resource, IProxy proxy, IParameters p) throws WcmException { if (resource==null)return null; TextView desc = new TextView(); desc.setWrapping(true); IVersionHistory vh = resource.getVersionHistory(); if (vh!=null) { desc.setText("#"+Integer.toString(vh.size())); desc.setTooltip("Version #"+vh.size()); } return desc; } }
178
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
UI Commands UI commands define actions on a resource level. They allow for the execution of arbitrary custom code on a resource or on a set of resources. Visibility and accessibility of commands can be controlled on a number of levels, including at the source code and UI configuration levels. A common way for more advanced users to access commands in KM is via the context (or hover) menu associated with each resource, as seen in the picture below. Here, a number of commands are visible, and the ability to build submenus using command structures is also shown.
Figure 88: Accessing Commands via the Context or Hover Menu
Implementations of new commands must extend the AbstractCommand class, and overwrite the raisesEvent() method. UI Commands (external content) – Implementation: • •
Extend AbstractCommand class Overwrite the raisesEvents() method – – –
Suppresse the screen flow part Allow execution of external URLs Implement a special method: getLinkAttributes()
Notice that screen flow events are supressed by the raisesEvent() method.
public class CustomExternalCommand extends AbstractCommand {
public ICommand getNewInstance()
2006/Q2
© 2006 SAP AG. All rights reserved.
179
Unit 7: Flexible UI
EP130
{ return this.initNewInstance(new SimpleExternalCommand()); } public IRenderingEvent execute(IScreenflowData arg0) throws WcmException { return null; } public boolean isExecutable() { return true; } public boolean raisesEvent() { return false; }
public LinkAttributes getLinkAttributes() { return new LinkAttributes("http://www.sap.com/", "_blank"); } }
UI Commands (with screenflow) – Implementation: • • •
Extend AbstractCommand class Implement Interface ISimpleExecution Support for one-step screen flow
•
– Multiple screens are currently not possible – Rendering is done in HTMLB Implement all execute() methods – –
Inital screen flow execute() Callback execute() – –
Does the action Handles errors
public class CustomScreenflowCommand extends AbstractCommand implements ISimpleExecution
180
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
{ public IRenderingEvent execute(IScreenflowData sfd) throws WcmException { TextView tv = new TextView("tvid"); tv.setText("Do you really want to do this ?"); ConfirmComponent cc = new ConfirmComponent( ConfirmComponent.OK_CANCEL, this.context.getLocale(), tv); String sRid = (String) this.values.get(0); RID rid = RID.getRID(sRid, null); OneStepScreenflow oscf = new OneStepScreenflow(sfd, this.getAlias(), rid, cc); return oscf.execute(); } public IRenderingEvent execute(IResource res, Event event) throws WcmException { if (event instanceof ConfirmEvent) { ConfirmEvent cce = (ConfirmEvent) event; if (ConfirmEvent.CHOICE_YES.equals(cce.getChoice())) { // do the action here ... return new InfoEvent(Status.OK, "Done !"); } else if (ConfirmEvent.CHOICE_NO.equals(cce.getChoice())) { return ConfirmComponent.onNo( event, res.getContext().getLocale()); } else if (ConfirmEvent.CHOICE_CANCEL.equals(cce.getChoice())) { return ConfirmComponent.onCancel( event, res.getContext().getLocale()); } } return new InfoEvent(Status.ABORT, "Aborted."); } }
return new InfoEvent(Status.ABORT, "Aborted.");
}
2006/Q2
© 2006 SAP AG. All rights reserved.
181
Unit 7: Flexible UI
EP130
b • • • • •
Bundle multiple flexible UI components in a deployable unit Extend abstract classes if possible Do not extend standard flexible UI components Activate the Rendering Information iView for debugging and tracing A flexible UI component's lifetime is limited to one request/response cycle
ResourceListFilter The resource list filter is now registered in the flexible UI runtime and can be added to any CollectionRenderer settings of the flexible UI configuration.
Figure 89: Flexible UI Components: ResourceListFilter
Hiding resources from the KM Navigation iView is a mandatory feature for most customer scenarios. Filters are normally registered in the repository framework and are applied to all resources called from the KM application. There is no difference between end-user calls and service calls, such as from crawlers or searches. The Resource List Filter service offers additional possibilities to filter only on the flexible UI runtime. Resource list filters can be activated on collection renderer settings and, therefore, are assigned more precisely than the repository framework filters.
182
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
Implementing IResourceListFilter and ICollectionListFilter Interfaces: •
IResourceListFilter interface (mandatory): – –
•
Filter list of resources (IResourceList) Take care on performance
– Huge list – Heavyweight objects (IResource) ICollectionListFilter interface (optional): – – –
Filter parent collection (ICollection) Prefilled PropertyNames to be fetched from repository framework Apply collator and prefilled properties to repository framework –
Significantly improves performance
Figure 90: Flexible UI Components: ResourceListFilter (2)
2006/Q2
© 2006 SAP AG. All rights reserved.
183
Unit 7: Flexible UI
EP130
Figure 91: Flexible UI Components: ResourceListFilter (3)
Within the flexible UI framework, both interfaces are called in a certain sequence. Due to the performance advantages of the ICollectionListFilter, this method is prioritized by the framework. Lifetime of ResourceListFilters instances: • • • •
New instance per rendering cycle Reduce the initialization time An instance is only processed once Make eligible for garbage collection
Figure 92: Flexible UI Components: ResourceListFilter (4)
184
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
The mapping from a Java class to a component alias can be carried out by choosing Content Management → Global Services → Resource List Filters. Create a new entry for the custom resource list filter.
Figure 93: Flexible UI Components: ResourceListFilter (5)
Ready-Mades Ready-mades: • • • •
2006/Q2
Easy -to-use flexible UI components Predefined functionality Encapsulate complex UI logic Can be used in any custom flexible UI component, for example, Collection/PropertyRenderer
© 2006 SAP AG. All rights reserved.
185
Unit 7: Flexible UI
EP130
Figure 94: Flexible UI Ready-Mades
Figure 95: Flexible UI Ready-Mades (2)
186
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Components
Available ready-mades: •
ResourceImage Renders an image or icon of the resource
•
ResourceLink Renders the content link to the specified resource with a certain UI component, for example, TextView or image
•
ResourceDetailsLink Renders the details link to a resource
•
PropertyComponent Renders a single property of a given resource into a TextView element
2006/Q2
© 2006 SAP AG. All rights reserved.
187
Unit 7: Flexible UI
EP130
Lesson Summary You should now be able to: • List which components of the Flex UI are customizable • Describe what each Flex UI component is used for
188
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Debugging
Lesson: Debugging Lesson Overview This lesson covers debugging support in the Flex UI.
Lesson Objectives After completing this lesson, you will be able to: •
Use the built-in facilities to debug flexible UI presentations
Business Example Your project has asked you to configure a new set of portal screens based on the Flex UI. You do this by copying the existing layout sets, collection renderers and other components and then making changes. You use the debugging functions to help support your configuration task.
Debugging Problems solved with flexible UI debugging: • • • • •
2006/Q2
Allow all classes to simply dump information into a container Provide a central flag to create all that information (performance!) Structure and evaluate information Separate information unique to the current iView from information that is the same across the VM Offer transfer of information into a file so it can be sent to SAP
© 2006 SAP AG. All rights reserved.
189
Unit 7: Flexible UI
EP130
Figure 96: Flexible UI: Debugging
Figure 97: Flexible UI: Debugging (2)
190
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Debugging
Figure 98: Flexible UI: Debugging (3)
Seven-step checklist: 1.
Is the wrong layout used for all users or just for certain users? Check 508 settings, permissions, time-based publishing, statemanagement, and feedback.
2.
Is the static UI information okay? Par-dependencies, typing errors, interface-implementations, getNewInstance()-method
3.
Faulty renderers: Check the CustomizingI Is the correct LayoutSet used? Is the correct layoutSetMode set?
4.
Check your renderers from the outside-in: LayoutController, CollectionRenderer, and so on Are the flavors and used classes okay? Are the parameters correct?
5.
Faulty renderers: Check the Customizing (2) Did you find a valid OTH? Did you find the OTH you expected?
6.
Faulty renderers: Check the Customizing (3) Have the folder settings been read? Has the default of the flexible UI been used?
7.
Faulty programming Identify the level from which the errors start and open an CSN ticket.
2006/Q2
© 2006 SAP AG. All rights reserved.
191
Unit 7: Flexible UI
192
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Debugging
Exercise 8: Flexible UI Exercise Objectives After completing this exercise, you will be able to: • Develop custom flexible UI components for rendering
Business Example Developing custom resource, collection, and property renderers is common. A custom property renderer may be used to render custom properties that require special rendering for display. The rating property is an example of a predelivered property that has a custom renderer that is different from the other renderers in KM. Layout controllers allow the customization of the layout of individual items on the screen.
Task: Please have a look at the SAP NetWeaver Developer Studio exercises delivered with this lesson. Try to understand what the code is doing and complete the TODOs in the code.
2006/Q2
© 2006 SAP AG. All rights reserved.
193
Unit 7: Flexible UI
EP130
Solution 8: Flexible UI Task: Please have a look at the SAP NetWeaver Developer Studio exercises delivered with this lesson. Try to understand what the code is doing and complete the TODOs in the code.
194
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Debugging
Lesson Summary You should now be able to: • Use the built-in facilities to debug flexible UI presentations
2006/Q2
© 2006 SAP AG. All rights reserved.
195
Unit Summary
EP130
Unit Summary You should now be able to: • Build custom UI elements and layouts using the flexible UI API • List which components of the flexible UI API are customizable via coding • List which components of the Flex UI are customizable • Describe what each Flex UI component is used for • Use the built-in facilities to debug flexible UI presentations
196
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 8 Search and Classification Unit Overview The Search and Classification API of KMC is a powerful tool that can help you provide custom search functionality to your end users or custom applications. This unit covers the basics of the Search and Classification API, as well as how to integrate third-party search engines into KM. Finally, we will cover customization of the KM search iView.
Unit Objectives After completing this unit, you will be able to: • • •
Explain how the search API fits into the KMC API Integrate a third-party search engine into KM Customize and enhance the KM Search iView
Unit Contents Lesson: Using the Indexmanagement API ..................................198 Exercise 9: Using the Index Management API in a Simple Portal Component ..................................................................207 Lesson: Integrating a Search Engine ........................................210 Lesson: Enhancing the KM Search iView ...................................224 Exercise 10: Developing Your Own Search Components.............239
2006/Q2
© 2006 SAP AG. All rights reserved.
197
Unit 8: Search and Classification
EP130
Lesson: Using the Indexmanagement API Lesson Overview Custom search components can be built by accessing the Index Management API directly from within components.
Lesson Objectives After completing this lesson, you will be able to: •
Explain how the search API fits into the KMC API
Business Example You have been asked by your project to develop a web service that allows limited access to search functionality in KM. You decide the best way to do this is to develop and EJB layer that accesses the indexmanagement API, and then to enable the EJBs as web services.
The Index Management API Searching in the SAP NetWeaver Portal is a key feature of the product and is a requirement in most customer project scenarios. Search functionality within the portal is exposed through the KM index management service, which offers a Java API to access the search capability in custom-developed components.
Figure 99: Architecture
198
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Indexmanagement API
The index management service is one of KM’s global services and is therefore not linked to a repository manager. The index management service provides functionality for managing index-based search and classification engines. The standard index service provided by SAP is the TREX index service, which enables the SAP NetWeaver Enterprise Portal to search in KM repositories. To use the search functionality from a client point of view, the KM Index Management API can be used in UI components such as portal components, Web Dynpro UIs, or servlets.
Figure 100: Search and Classification
Prerequisites: • • •
Fully installed and configured TREX A KM repository containing some documents for indexing and searching At least one index created for the KM repository containing the documents.
Relevant KM APIs: • •
2006/Q2
com.sapportals.wcm.service.indexmanagement.*: Provides a service for managing indexes com.sapportals.wcm.service.indexmanagement.retrieval. search.*: Provides functions for searching and text mining
© 2006 SAP AG. All rights reserved.
199
Unit 8: Search and Classification
EP130
Figure 101: Using the Search Interfaces
The IFederatedSearch interface allows you to search over all active index services of KM Index Management. By default, the only index service available is TREX. An index service itself can manage several indexes, which can also be included in the search execution.
Figure 102: Build a Search Query
200
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Indexmanagement API
Figure 103: Build a Search Query (2)
Figure 104: Build a Search Query (3)
2006/Q2
© 2006 SAP AG. All rights reserved.
201
Unit 8: Search and Classification
EP130
Figure 105: Execution of the Search
The searchWithSession() method is recommended to execute a search on KM Index Management. This method ensures that only the requested results, instead of all results, are later retrieved by the index service implementation.
202
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Indexmanagement API
Figure 106: Handling of the Search Result
Note: For performance reasons, we recommend you retrieve only a subset of the search result items instead of all. Also, a paging mechanism should be introduced on an appropriate user interface. In addition to the resource object, other search-relevant information can be retrieved out of a single result item, such as rank value, a content snippet, or search-specific properties: • • •
2006/Q2
result.getRankValue(); result.getContentSnippet(); result.getLocalProperties();
© 2006 SAP AG. All rights reserved.
203
Unit 8: Search and Classification
EP130
Prerequisites for integration of third-party search engines: •
Third-party search engine is accessible using Web technologies –
• •
Best method: Third-party engine provides a Java API that can be deployed on a J2EE server – Alternate method: Results coming from a query of a third-party engine must be “readable,” for example, as XML or as a structured document – A mapping of third-party search engine information to KM-compliant information must be possible, for example, the result should contain a title or a description The result of the third-party search engine must be accessible using HTTP(s) Optional: A user mapping for authorization is possible (required in relation to content restrictions)
If there is no support directly via a Java API, a wrapper technology such as an HTTP wrapper has to be used to communicate with the index management layer
Figure 107: Integration of Third-Party Search Engines
In the sample implementation, shown above, a third-party search engine delivers its own index type. This means that we have to implement our own index collection and our own virtual index. A third-party search engine does not usually offer an interface to its index implementation, even if an index exists. In this case, the index management virtual index has to be implemented as a search trigger for the third-party search engine. This means that instead of calling the index itself, a search is executed using the API of the third-party search engine.
204
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Indexmanagement API
The result of such a search execution has to be transformed into result objects that are compliant with KM Index Management. For this reason, certain information, such as an access path, meta information, and ranking information has to be provided by the third-party search engine. KM-compliant results must be accessible using a URI or RIDs and need to be filled with KM-specific information such as a document ID, a title, or an author. Integration steps: •
• •
2006/Q2
Virtual index: Implements a logical index object for the third-party search engine. This implementation is mandatory even if the third-party search engine does not support indexes. An empty implementation can also be provided. Virtual index collection: Implements the call of a single virtual index and/or the query of the third-party search engine. Wrapper for third-party search engines: If the third-party search engine does not provide a Java API, a kind of technology wrapper has to be built up to communicate with KM Index Management. Most the third-party search engines offer an HTTP/XML interface, so an HTTP/Java wrapper has to be used.
© 2006 SAP AG. All rights reserved.
205
Unit 8: Search and Classification
206
© 2006 SAP AG. All rights reserved.
EP130
2006/Q2
EP130
Lesson: Using the Indexmanagement API
Exercise 9: Using the Index Management API in a Simple Portal Component Exercise Objectives After completing this exercise, you will be able to: • Use the Index Management API to integrate search functionality into custom components
Business Example This API allows the developer access to custom search functionality. A highly customized search screen or integration of TREX into another search client or fat client are two good examples of where this could be useful.
Task: Develop an iView with the following characteristics
2006/Q2
1.
Takes a single input parameter
2.
Executes a search using the input parameter
3.
Displays the results
© 2006 SAP AG. All rights reserved.
207
Unit 8: Search and Classification
EP130
Solution 9: Using the Index Management API in a Simple Portal Component Task: Develop an iView with the following characteristics 1.
Takes a single input parameter a)
2.
Executes a search using the input parameter a)
3.
–
Displays the results a)
208
–
–
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Using the Indexmanagement API
Lesson Summary You should now be able to: • Explain how the search API fits into the KMC API
2006/Q2
© 2006 SAP AG. All rights reserved.
209
Unit 8: Search and Classification
EP130
Lesson: Integrating a Search Engine Lesson Overview The Knowledge Management (KM) and Repository Framework APIs offer the possibility of implementing your own index services for the KM Index Management service. The index management service consolidates all search results coming from the different index service implementations and presents them in a unique way – using KM’s flexible user interface – to the end user. Results can be shuffled, grouped by certain criteria, and rendered by standard KM technology without any additional development effort.
Lesson Objectives After completing this lesson, you will be able to: •
Integrate a third-party search engine into KM
Business Example Your company wants to present a single search interface to corporate end users. You currently use a third-party product to provide search functionality. You want to integrate it by using the KM Index Management service.
Search Engine Integration The index management service is a global service and is therefore not linked to a repository manager and independent of any single repository. The service allows for the management of search and classification engines.
Architecture of Index Management The following diagram shows the basic concepts behind this management functionality.
210
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Integrating a Search Engine
Figure 108: Architecture of Index Management
The diagram shows that the index management service manages collections of indices represented by ISearchIndexCollection objects, also known as index collections. An index collection groups indices of the same type. In the diagram, the third-party search engine on the right delivers its own index type, and so it is aggregated by its own index collection. This would need to be implemented, along with the virtual index, if the third-party search engine were to be integrated into KM. The virtual index serves as a representation of the search engine's index, which is often not accessible in integration scenarios. In this case, the virtual index needs to be implemented as a search trigger for the third-party engine in question. When a search request is initiated using the search user interface or the search API, the index management service determines which index to use based on the configured indices. The virtual index then passes the search request to the third-party engine. The result of such a search execution has to be transformed into KM index management compliant result objects. For this reason, certain information such as an access path, meta information, and ranking information has to be provided by the third-party search engine. KM-compliant results must be accessible using a URI or CM-conform RIDs (Resource IDs) and need to be filled with KM- specific information such as a document ID, a title, or an author.
2006/Q2
© 2006 SAP AG. All rights reserved.
211
Unit 8: Search and Classification
EP130
Requirements for the Third-Party Search Engines To integrate a third-party search engine, the following prerequisites should be fulfilled by the engine: • •
third-party search engine is accessible using Web technologies: –
• •
Best method: third-party engine provides a Java API that can be deployed on a J2EE server – A mapping of third-party search engine information to KM-compliant information must be possible, for example, result should contain a title, or a description – Alternative method: Results coming from a query of a third-party engine must be "readable", for example, as XML or as a structured document The result of the third-party search engine must be accessible using HTTP(s) Optional: A user mapping for authorization is possible (required in relation to content restrictions)
Index Management API in Detail This section provides more detail on the index management API using a simple integration scenario that is to be implemented. The relevant packages for using the index management API are • • •
212
com.sapportals.wcm.service.indexmanagement povides a service for managing indexes com.sapportals.wcm.service.indexmanagement.retrieval.search provides functions for searching and text mining com.sapportals.wcm.repository contains the basic repository framework interfaces and classes
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Integrating a Search Engine
In a simple scenario, a third-party search engine is to be integrated into KM using the index management API as outlined in the architectural diagram above. The coding for this task is divided into three implementation objects: •
• •
Virtual index: Implements a logical index object for the third-party search engine. This implementation is mandatory even if the third-party search engine does not support indexes. An empty implementation can also be provided. Virtual index collection: Implements the call of a single virtual index and/or the query of the third-party search engine Wrapper for third-party search engines: If the third-party search engine does not provide a Java API, a kind of technology wrapper has to be built up to communicate with KM index management. Most of the third-party search engines offer an HTTP/XML interface, so an HTTP/Java wrapper has to be used.
Implementing a Virtual Index A virtual index implementation should extend the com.sapportals.wcm.service.indexmanagement.AbstractIndex class and must implement the com.sapportals.wcm.service.indexmanagement.retrieval.search.ISearchIndex. The AbstractIndex class implements basic index managing functionality such as the creation and deletion of indices. These functions can be used for managing the physical index of the third-party search engine. If a third-party search engine does not support indexes, the implementation is still necessary but could be left as an empty (dummy) index implementation.
Figure 109: Virtual Index public class CustomerSearchIndex extends AbstractIndex implements ISearchIndex ...
The generated index must be registered with the corresponding index collection implementation. This can be carried out when the constructor is called.
2006/Q2
© 2006 SAP AG. All rights reserved.
213
Unit 8: Search and Classification
EP130
public CustomerSearchIndex( String indexId, String indexName, String indexGroup, IIndexFolderList indexFolders, String serviceId, String profileId, String serviceUserId, Properties indexServiceProperties)
throws WcmException { super(...); Collection indexes = new ArrayList(); indexes.add((IIndex) this); m_searchIndexCollection = new CustomerSearchIndexCollection(indexes); }
The index implementation must return a valid set of supported options. For search indexes, the options SupportedOption.SEARCH and SupportedOption.SEARCH_RESULTS_SORTED_BY_PROPERTY should be returned. private final static ISupportedOptionSet SUPPORTED_OPTIONS = new SupportedOptionSet();
static { SUPPORTED_OPTIONS.add(SupportedOption.SEARCH); SUPPORTED_OPTIONS.add(SupportedOption.SEARCH_RESULTS_SORTED_BY_PROPERTY);
} : public ISupportedOptionSet getSupportedOptions() {
return SUPPORTED_OPTIONS; }
The service type defines the usage of the index within the index management service. A search index is used for this implementation, but it is also possible to have a search and classification type.
public List getServiceTypes() {
List serviceTypes = new ArrayList(); serviceTypes.add(IWcmIndexConst.SERVICE_TYPE_SEARCH);
214
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Integrating a Search Engine
return serviceTypes; }
The virtual index generation is carried out by calling the generate() method of the index implementation. By default, the internalSaveIndex() method of the IIndexService interface has to be called.
public void generate(IResourceContext ctxt) throws WcmException { IIndexService indexService = (IIndexService) ResourceFactory.getInstance().getServiceFactory(). getService(IServiceTypesConst.INDEX_SERVICE); try { indexService.internalSaveIndex((IIndex) this); } catch (ResourceException e) { throw new WcmException(e); } }
In addition to the methods given here, the delete() method must be implemented. This method deletes the virtual index in the index management object. All other methods that are not mentioned here can be left with a default implementation or should throw a NotSupportedException(...).
Implementing a Virtual Index Collection
Figure 110: ISearchIndexCollection
2006/Q2
© 2006 SAP AG. All rights reserved.
215
Unit 8: Search and Classification
EP130
The ISearchIndexCollection implementation is the execution container of virtual indexes of the same type. Therefore, every third-party search engine needs its own virtual index and collection implementation. The collection implementation is the central access point for the index management service for triggering the search and fetching the search results from the third-party engine. An implementation can directly implement the ISearchIndexCollection interface or extend the abstract class AbstractSearchIndexCollection. The abstract class reduces the implementation time by offering multiple default implemented methods: public class CustomerSearchIndexCollection extends AbstractSearchIndexCollection ...
The most important method signatures to be implemented are executeQueryWithSession(...) and getSearchResult(...). Both methods come with multiple method signatures that do not have to be implemented all, but have a redirect to the corresponding method with most of the parameters specified.
public ISearchSession executeQueryWithSession(IQueryEntryList queryEntryList,
IResourceContext context, int initNumberMaxRawResults, ICollection searchFromHere, ISortPropertyName sortProperty, Set set) throws WcmException
The executeQueryWithSession(...) method encapsulates the search result in a stateful session object. This session object can be created with the getNewSearchSession() method of the AbstractSearchIndexCollection class:
ISearchSession session = this.getNewSearchSession(queryEntryList,
searchFromHere, this, context, initNumberMaxRawResults, sortProperty );
IRawSearchSession rawSession = (IRawSearchSession) session;
216
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Integrating a Search Engine
The query parameters specified on the UI are passed to the executeQueryWithSession() method and must be transformed into third-party search engine compliant queries:
String queryString = ""; IQueryEntryListIterator queriesIterator = queryEntryList.listIterator(); IQueryEntry query = null;
while (queriesIterator.hasNext()) { query = queriesIterator.next(); if (query.getRowType().equals(IQueryEntry.ROW_TYPE_TERM)) {
queryString += "+"+query.getValueAsString(); } }
The query must than be passed to the third-party search engine implementation, and the query is executed. The raw search results have to be placed into the search session object. The raw search results are now third-party search engine dependent and need to be transformed into KM-compliant results in the next step.
FooSearch search = new FooSearch();
FooResult[] resultElements = search.doSearch(queryString); List rawResultList = this.getRawSearchResultList(resultElements, rawSession, initNumberMaxRawResults);
rawSession.setRawSearchResults(rawResultList);
The raw search results are passed by the index management service to the implemented getSearchResults(...) method. The transformation of the raw results into KM compliant results must be carried out within this method. This means that all results of the third-party search engine have to be transformed into IResource objects.
2006/Q2
© 2006 SAP AG. All rights reserved.
217
Unit 8: Search and Classification
EP130
public ISearchResultList getSearchResults(List rawSearchResults, ResourceContext context) throws ResourceException
To generate valid KM IResource objects, the result URL of the raw result has to be transformed into a KM RID object.
IURLGeneratorService urlGenerator = (IURLGeneratorService)
ResourceFactory.getInstance().getServiceFactory(). getService(IServiceTypes Const.URLGENERATOR_SERVICE);
IUri resultUri = UriFactory.parseUri(rawResult.getDocKey()); RID rid = urlGenerator.mapUri(resultUri);
For every RID object, a corresponding IResource object is created during Runtime. The IResource object has to be encapsulated in an ISearchResult object, which is the KM-compliant result format. ISearchResult searchResult = this.createSearchResultObject(resource, 1.0F);
Methods to be implemented in the virtual index collection implementation are listed in the table below. Methods which are not listed here might be implemented or should throw a corresponding exception: Methods for implemantation of virtual index collection
218
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Integrating a Search Engine
Methods for implemantation of virtual index collection Method
Purpose
executeQueryWithSession()
Executes the query to a third-party index or to the search engines interfaces and retrieves raw search results to a stateful session object.
executeQuery()
Similar to executeQueryWithSession(), but the results are not held in a session object. The search is stateless.
getSearchResults()
Retrieves the raw search result data and places it into KM-compliant result objects (ISearchResult). The objects accessible using a URI must be provided with a valid rank value.
searchSimilarDocumentsWithSession()
Returns result objects similar to the provided information data. This method might be implemented or should throw a corresponding NotSupportedException object.
Implementing a Wrapper for third-Party Search Engines third-party search engines that do not offer a Java API for retrieving search results can also be used for integration in KM index management. As well as the Java API, the HTTP interface with XML as content format is also supported. It is therefore necessary to implement a Java HTTP Bridge. The Java HTTP Bridge implementation depends on the third-party search engine result format. The result of an HTTP response has to be parsed and transformed into KM-compliant result objects. Take a look at the following example implementation of FooSearch:
public FooResult[] doSearch(String query) throws Exception { DOMParser parser = new DOMParser();
parser.parse("http://www.foosearch.com/qxml.php?q="+query); this.m_resultDom = parser.getDocument();
return this.createFooResults();
2006/Q2
© 2006 SAP AG. All rights reserved.
219
Unit 8: Search and Classification
EP130
}
The third-party search engine has its own schema for search results. They have to be transferred to KM’s index management. Third-party search engine metadata information has to be mapped to KM properties:
private FooResult[] createFooResults() {
NodeList n = this.m_resultDom.getElementsByTagName("RESULT"); FooResult[] result = new FooResult[n.getLength()]; for (int i = 0; i < n.getLength(); i++) { result[i] = new FooResult();
Node node = n.item(i); if (node.hasAttributes()) { NamedNodeMap nmap = node.getAttributes(); result[i].setResultID(nmap.getNamedItem("ID").getNodeValue());
} NodeList children = node.getChildNodes(); for (int j = 0; j < children.getLength(); j++) { Node child = children.item(j);
if (child.getNodeName().equalsIgnoreCase("title")) {
result[i].setTitle( child.getChildNodes().item(0).getNodeValue());
} if (child.getNodeName().equalsIgnoreCase("url"))
220
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Integrating a Search Engine
{
result[i].setUrl( child.getChildNodes().item(0).getNodeValue());
} } } }
The FooSearch instance is called within the executeQueryWithSession() method of the ISearchIndexCollection implementation:
public ISearchSession executeQueryWithSession(...) { // .. logic here
FooSearch searchEngineObject = new FooSearch(); if (searchEngineObject != null) { try { rawResultList = searchEngineObject.doSearch(query); } catch (Exception e1) { e1.printStackTrace(); }
} }
The transformation of the third-party search results into KM-compliant result objects has to be carried out in the executeQueryWithSession() method.
2006/Q2
© 2006 SAP AG. All rights reserved.
221
Unit 8: Search and Classification
EP130
Restrictions Currently there are certain restrictions to this kind of 3rd-party search engine integration. •
Ranking Problems/Normalization Ranking algorithms for several search engines differ in the result. This means that the same rank value from search engine A and from search engine B can express different rankings. However, if you merge search results from different search engine, a normalized rank value is needed. There is currently no normalization possibility between rank values of different search engines, because the algorithms used in the search engine implementation are not actually known.
•
Presentation of Results Search results provided by the index management service are presented by the KM flexible user interface. This means that results are always presented using HTMLB technology. The flexible UI can be extended by implementing your own rendering controls such as collection renderers or resource renderers.
•
Legal issues If you use the described coding and configuration to access externally provided search functionality that your organization does not own such as a search service on the Web, you must request a licence from the respective provider. Failing to do so may be illegal. The conditions for such a licence are usually published on the respective Web search provider's Web pages.
222
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Integrating a Search Engine
Lesson Summary You should now be able to: • Integrate a third-party search engine into KM
2006/Q2
© 2006 SAP AG. All rights reserved.
223
Unit 8: Search and Classification
EP130
Lesson: Enhancing the KM Search iView Lesson Overview Customizable search interfaces are absolutely necessary for providing company-specific search functionality for KM content. Since the introduction of functionality for creating search dialogs with search components, it is possible to develop customized search components and plug them into the standard KM Search iView.
Lesson Objectives After completing this lesson, you will be able to: •
Customize and enhance the KM Search iView
Business Example Your project has asked you to add company specific buzzword-search capability to the search user interface. This would allow end users to select from a list of predefined common buzzwords for which to search. You decide you need to modify the KM search iView to provide this functionality.
The KM Search iView The KM search iView provides a common look and feel for search results delivered from all indices registered with the index management service. The results are rendered by the appropriate resource and collection renderers configured for the LayoutSet used in the search iView. The search iView is launched either from the portal header or via a KM command with the KM navigation iView. The following screenshot shows how the search iView is broken down into components.
224
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
Figure 111: Areas of the Search iView
Additionally, the header area of the search iView allows for the specification of more advanced search options used to further restrict the result set.
Figure 112: Header Area of the Search iView
2006/Q2
© 2006 SAP AG. All rights reserved.
225
Unit 8: Search and Classification
EP130
Search Components The standard KM search iView offers the capability of plugging in custom-developed search components that define certain areas of the iView. Developing new search components means implementing the ISearchComponent interface. • • •
Flexibility: More possibilities in configuration of several search iViews Modularization: A set of standard search components are delivered Extensibility: Customers can implement their own search components
The following diagram shows some of the standard search components available in KM.
Figure 113: Standard Search Components
The standard_search component combines features such as a search input area, related terms area, and search options.
Implementing an ISearchComponent Developing new search components means implementing the ISearchComponent interface. The ISearchComponent interface offers some important method signatures to be implemented in order to get a valid search component. To render the control in the standard search iView, an HTMLB compliant control has to be returned by the renderComponent() method:
226
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
public Component renderComponent() throws SearchException {
For example, take any HTMLB layout object for defining a certain area within the standard search iView:
GridLayout grid = new GridLayout(); grid.setWidth("100%");
grid.setCellPadding(5); grid.addComponent(2, 1, this.createHeader()); grid.addComponent(3, 1, this.createBody());
grid.addComponent(4, 1, new HTMLFragment("< hr size=\"1\">")); return grid;
The method should throw a SearchException when an error occurs during rendering. The rendered HTMLB component can contain all HTMLB controls that can be used for input handling from the user, such as InputField, Checkbox, Radiobuttons:
GridLayout grid = new GridLayout();
grid.setWidth("100%"); int col = 1, row = 1; for (int i = 0; i < SimpleSearchComponent.m_buzzwords.length; i++) { if (i % 7 == 0) { col = 1;
row++; } Checkbox c = new Checkbox(SimpleSearchComponent.m_buzzwords[i]);
2006/Q2
© 2006 SAP AG. All rights reserved.
227
Unit 8: Search and Classification
EP130
c.setText(value);
c.setChecked(false); grid.addComponent(row, col, c); col++;
} return grid; }
After the UI is rendered by the standard KM search iView and the user executes the search by pressing the search button, the UI elements of the rendered search component are evaluated by the standard KM search iView by calling the setDynpage() method. It provides access to every HTMLB element that is placed on the layout control:
public void setDynPage(DynPage dynPage) { StringBuffer searchWord = new StringBuffer();
Component c = null;
Retrieve all UI elements from the current Dynpage. Do not persist the dynpage object itself. It is created anew for every server roundtrip.
for (int i = 0; i < SimpleSearchComponent.m_buzzwords.length; i++) {
c = dynPage.getComponentByName( SimpleSearchComponent.m_buzzwords[i]); if (c != null && c instanceof Checkbox) { if (((Checkbox) c).isChecked()) { searchWord.append(c.getId());
228
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
searchWord.append(SimpleSearchComponent.SEPARATOR);
} } }
The values of every UI element can be stored in the local persistent map, which is validated for every server roundtrip for the corresponding search component:
this.getPersistenceMap().setProperty(
SimpleSearchComponent.PRP_SEARCH_WORDS, searchWord.toString()); }
The result of an executed search can be modified by adding a valid query (IQueryEntryList) created by the information specified in the UI elements. The query itself must be put in a SearchParamsMap object that contains search-relevant key value pairs:
public SearchParamsMap getSearchParamsMap() { SearchParamsMap m = new SearchParamsMap(); try {
IQueryEntryList list = this.createQuery();
The IQueryEntryList must be put into the SearchParamsMap object with a certain key:
m.put(SearchParamConst.PARAM_SEARCH_QUERY_ENTRIES, list);
} catch (WcmException e) { e.printStackTrace(); }
return m;
2006/Q2
© 2006 SAP AG. All rights reserved.
229
Unit 8: Search and Classification
EP130
}
SearchParamConst.PARAM_SEARCH_QUERY_ENTRIES key is evaluated by the standard KM search iView. You can put in the following subset of keys defined in the SearchParamConst class:
230
Parameter
Purpose
Type
Possible values
PARAM _ SEARCH _ IN
Search scope selection
String
SEARCH_INDEXES SEARCH_FROM _FOLDER (-> Search Folder)
PARAM_SEARCH Search folder (-> String _FOLDER PARAM_SEARCH_IN)
Example: /documents
PARAM_SEARCH Search query list _QUERY_ENTRIES
IQueryEntryList
Complex object that can be built by SearchQueryBuilder
PARAM_INDICES _LIST
Index list to be searched on
ArrayList
Array list of index objects
PARAM_SORT _PROP_NAME
Property for sorting the search results
ISortPropertyName
CM property object with sort order (has major priority)
PARAM_SORT _ORDER
Sort order of search result
String
DESCENDING,ASCENDING
PARAM_SORT _OPTION
Property ID for sorting search results
String
PARAM_MATCHES_PER_PAGE Number of search results per page
String
Numeric values: 5,10,20,50
PARAM _ ALLOWED _SORT_PROPS
String
Example: displayname,modified,modifiedby
Property IDs of allowed sort properties to be shown in the search result header (csv)
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
PARAM_MAX _NOF_CATEGORIES
Maximum number of categories to be displayed for one search result
String
Numeric values: 0,1,2,3,4,6,9999
PARAM Defines content _MAX_SNIPPET snippet length _WORDS for search result abstracts
String
Numeric values 0-200
PARAM_ENABLE _SEARCH_CASCADE
Boolean
true,false
String
Example: Banana
Enables cascaded search (see documentation)
PARAM Search term for _SEARCH_TERM display in search result header; is not taken into account for query PARAM _ERRORS _OCCURREDOCCURED (read-only)
Return value that Boolean indicates that at least one error occurred in at least one component; Is set to true when provided messageList of components is not empty; useful when input checks have to be performed;
true, false
PARAM_JUST _SEARCHED (read-only)
Return value that indicates that a search was performed
true
Boolean
Keep in mind that all keys stored in the merged map of the standard KM search iView are overwritten by the last placed value, except the key SearchParamConst.PARAM_SEARCH_QUERY_ENTRIES. This key’s values are connected by a logical AND
2006/Q2
© 2006 SAP AG. All rights reserved.
231
Unit 8: Search and Classification
EP130
In case no parameter is specified, the parameter’s values are taken from the defined Search option set. If no special option set is choosen the default values are taken. It is recommended to customize UI settings within the KM config iView -> Content Management -> UserInterface -> Search. A helper method for creating valid IQueryEntryLists could look like this:
private IQueryEntryList createQuery() throws WcmException {
StringBuffer query = new StringBuffer(); StringTokenizer words = new StringTokenizer(
this.getPersistenceMap().getProperty( SimpleSearchComponent.PRP_SEARCH_WORDS, "" ), SimpleSearchComponent.SEPARATOR);
Create a simple search term by concatenating a string object out of UI elements stored in the persistence map.
while (words.hasMoreTokens()){
query.append(words.nextToken()); if (words.hasMoreTokens()) query.append(SimpleSearchComponent.OPERATOR);
}
Create a valid IQueryEntryList object retrieved from the standard SearchQueryBuilder instance.
SearchQueryBuilder sqb = new SearchQueryBuilder();
sqb.setSearchTerm(query.toString());
return sqb.buildSearchQueryEntries();
232
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
}
Alternatively, you can build your own IQueryEntryList objects retrieving an empty instance from the IFederatedSearch:
IIndexService indexService = (IIndexService) ResourceFactory .getInstance()
.getServiceFactory() .getService( IServiceTypesConst.INDEX_SERVICE);
IFederatedSearch federatedSearch = (IFederatedSearch) indexService.getObjectInstance(
IWcmIndexConst.FEDERATED_SEARCH_INSTANCE);
IQueryEntryList qel = federatedSearch.getNewQueryEntryList();
IPropertyName propName = new PropertyName( PropertyName.createDisplayname().getNamespace(),
earchParamConst.PROP_NAME_COLLECTION);
Create a query and set the important attributes and add a new entry to the entry list.
IQueryEntry queryEntry = federatedSearch.getNewQueryEntry();
queryEntry.setPropertyName(propName); queryEntry.setRowType(IQueryEntry.ROW_TYPE_ATTRIBUTE);
2006/Q2
© 2006 SAP AG. All rights reserved.
233
Unit 8: Search and Classification
EP130
queryEntry.setValue("true"); queryEntry.setPropertyOperator(
IQueryEntry.PROPERTY_OPERATOR_EQUAL ); queryEntry.setTermWeight(1.0F);
qel.add(queryEntry);
Using Events In addition to just rendering further search controls, you also have the possibility to fire search related events, e.g. OnSearch or OnSearchOptions. Both events can be propagated from any HTMLB control of your search component. Simply create a new HTMLB control with certain attributes set, e.g. an HTMLB link,
Link link = new Link(this.createCompositeComponentId("LINK")); link.setOnClick("onClick");
If the link is clicked by a user later on, the method onClick(Event e) is triggered by the search framework. It is important to know, that the called method name corresponds to the value of the setOnClick() call. The attribute value onSearchClick link.setOnClick("onSearchClick");
is mapped to the method call public Event onSearchClick(Event event) {}
Keep in mind that at least one valid method must exist in your implementation. Within your event process method you have to read the event from the passed HTMLB event object and dispatch it to the search framework
234
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
SearchStartEvent searchStartEvent =
new SearchStartEvent( this.getId(),
SearchParamConst.EVENT_ON_SEARCH null);
The SearchStartEvent class simply wraps the HTMLB event, adds additional information, e.g. the search event type and passes it to the search framework. It can be executed by any HTMLB control, e.g. Link, DropDownBox or CheckBox. Currently the following search event types are available:
Configuration After deployment of the search component within a valid PAR file structure, the technical mapping has to be carried out in the user interface configuration of the KM configuration iView. The mapping from a Java class to a component alias can be carried out at Content Management -> User Interface -> Mapping -> Search Dialog Box Component. Create a new entry for the custom search component. A unique alias and a valid Java class must be provided. The java class specified here must implement the ISearchComponent interface and contain the methods mentioned above. After performing this configuration, the search component set is registered in the KM infrastructure. It can be configured as a component of a certain component set. A search component set is used in a search iView instance.
2006/Q2
© 2006 SAP AG. All rights reserved.
235
Unit 8: Search and Classification
EP130
Figure 114: Configuration: Technical Mapping
Technical mapping is only necessary if custom components have to be configured. All standard search components are already delivered with an appropriate configuration.
Figure 115: Configuration: SearchComponent Set Assignment
236
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
Figure 116: Configuration: SearchComponent Set Assignment (2)
Figure 117: Configuration: Portal Content Studio
2006/Q2
© 2006 SAP AG. All rights reserved.
237
Unit 8: Search and Classification
238
© 2006 SAP AG. All rights reserved.
EP130
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
Exercise 10: Developing Your Own Search Components Exercise Objectives After completing this exercise, you will be able to: • Develop a new search component • Plug your search component into the standard KM Search iView
Business Example Task 1: Develop a search component 1.
Develop a search component.
Task 2: Deploy the search component 1.
Deploy the search component.
Task 3: Configure the search component 1.
Configure the search component.
Task 4: Test the new search component 1.
2006/Q2
Test the new search component.
© 2006 SAP AG. All rights reserved.
239
Unit 8: Search and Classification
EP130
Solution 10: Developing Your Own Search Components Task 1: Develop a search component 1.
Develop a search component. a)
Follow the TODO Tags in the exercise project.
Task 2: Deploy the search component 1.
Deploy the search component. a)
Choose File → export → PAR File.
b)
Select the current project.
c)
Specify the portal server for deployment and press the Finish button.
Task 3: Configure the search component 1.
Configure the search component. a)
Log on to the portal with an administrator user.
b)
Choose System Administration → System Configuration → Knowledge Management → Content management → User Interface → Search UI.
c)
Choose Technical Mapping → Create a new SearchComponent entry.
d)
Specify the full qualified class name as the Class name parameter, for example, com.sap.examples.search.SampleSearchComponent.
e)
Choose SearchComponentSet and select an existing SearchComponentSet entry. Open it for editing.
f)
Assign your newly created technical mapping to the SearchComponentSet entry.
Continued on next page
240
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Enhancing the KM Search iView
Task 4: Test the new search component 1.
2006/Q2
Test the new search component. a)
Open the standard KM Search iView.
b)
Specify a search query.
c)
Execute the search.
© 2006 SAP AG. All rights reserved.
241
Unit 8: Search and Classification
EP130
Lesson Summary You should now be able to: • Customize and enhance the KM Search iView
242
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Unit Summary
Unit Summary You should now be able to: • Explain how the search API fits into the KMC API • Integrate a third-party search engine into KM • Customize and enhance the KM Search iView
2006/Q2
© 2006 SAP AG. All rights reserved.
243
Unit Summary
244
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 9 Collaboration Room Infrastructure Unit Overview Collaboration Rooms give users the ability to collaborate and communicate within the portal, regardless of physical location and across time zones. This unit covers the basics of the infrastructure used to achieve this.
Unit Objectives After completing this unit, you will be able to: •
Describe the Collaboration Room Infrastructure
Unit Contents Lesson: Collaboration Room Infrastructure .................................246
2006/Q2
© 2006 SAP AG. All rights reserved.
245
Unit 9: Collaboration Room Infrastructure
EP130
Lesson: Collaboration Room Infrastructure Lesson Overview The collaboration room infrastructure or framework combines functional aspects of the portal and KM platform to allow users to organize their team work, project work or company-wide collaboration in rooms. The infrastructure stores its information in the portal content directory and user management engine, and uses the repository framework to persist content.
Lesson Objectives After completing this lesson, you will be able to: •
Describe the Collaboration Room Infrastructure
Business Example Your project has asked you to set up a collaboration room suitable for sharing discussing documents within the context of the project. In order to do this, you use the standard delivered iViews to create a discussion room based on a predelivered template.
Collaboration Room Infrastructure The collaboration room infrastructure or framework combines functional aspects of the portal and KM platform to allow users to organize their team work, project work or company-wide collaboration in rooms. A room is a configurable virtual working environment in the portal. Members of a room are able to collaborate on documents, share documents and links with one another, track work tasks and search the rooms for information, among other tasks. There is a set of standard iViews for room creation and administrative functions. Carrying out advanced or custom tasks in rooms is done via the collaboration room API, discussed in the next unit. This unit covers the basics of the collaboration room infrastructure and how it utilizes KM and portal services to store its data. Three main parts of NetWeaver Portal and NetWeaver KM are used to store rooms and room-related information. These are the portal content directory (PCD), user management (ume) and repository framework (RF).
246
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Room Infrastructure
The PCD is used to store the portal-related parts of existing room instances, such as worksets, pages and iViews. It also is used to store room templates used to make the room creation process easier for end users. These templates are set up by an administrator and used by users with permission to create rooms. Permission to create rooms is given to members of the CollaborationRoomCreation portal role. •
portal_content/com.sap.ip.collaboration/Worksets Worksets that are used when creating a collaboration room Template
•
portal_content/com.sap.ip.collaboration/TemplateWorksets Worksets of collaboration room templates
•
portal_content/com.sap.ip.collaboration/RoomPartTemplateWorksets Worksets of collaboration room part templates
•
portal_content/com.sap.ip.collaboration/Rooms PCD objects of instantiated collaboration rooms (not visible)
The portal user management is used to store user-to-room assignment information as well as room role assignments for each user. During room creation, a UME group is created that holds all members of that room. Individual room roles (such as room administrator status) are stored as IPrincipalSet objects in the UME and are hidden from users of the collaboration API. Users should manipulate room role membership using the appropriate methods in the room API. The repository framework is used to create a semantic object for each room. These objects hold all room information (name and description of the room, as well as other basic information) that is not stored in one of the other two layers. The /rooms repository contains the root room objects with basic properties for each room, such as the description and basic role information. The /room_structures repository contains the structures of each room, such as which folders belong to each room. The /room_extensions repository is a standard repository that is used when creating storages for rooms. Finally, the /room_stores repository is a deprecated repository that is no longer used. Note: The RFExplorer tool is a good way to browse basic repository structures and view content and properties of resources. An article describing its installation and use can be found on the SAP Developer Network (SDN) at www.sdn.sap.com by searching for “RFExplorer”. The template used to create a room defines what attributes the room will have. From the template, the system adopts the navigation structure and the page layout, as well as the content, permissions and default settings for the application scenario of the room.
2006/Q2
© 2006 SAP AG. All rights reserved.
247
Unit 9: Collaboration Room Infrastructure
EP130
What happens when a collaboration room is being created? Which steps are performed by the Collaboration Room framework? 1.
Application calls
2.
• The Rooms API method createRoom() • Passes all relevant data for the new room as a parameter The Collaboration Room back end calls the User Management API to • •
3.
Creates a user group containing all users of the new room Creates a user group for each room role containing the users assigned to the role in question. These groups are hidden to end users of the portal's user management functions. Repository Framework API is called •
4.
Creates a public and a private folder for each selected content store (in the template) • Copies content from the content template folders to the new private folders • Creates a Public Area folder containing links to all new public folders • Create a Structure folder containing links to all new private folders and another link to the Public Area folder • Sets appropriate ACL permissions for all these new folders in the structure Repository Framework API is called •
5.
Creates a new folder resource in a special repository that represents the room itself • Sets the name, description, and so on of the room as properties of the new room resource • Creates a link from the room resource to the room Structure folder • Sets ACL permissions for the room resource The Portal Connector API is called •
6.
Copies the template workset (including pages and iViews) into a special PCD folder • Maps all room parameters (including hidden parameters such as room ID and so on) to the iView parameters according to the mapping rules defined in the template Groupware API is called
7.
• Sends invitation e-mails to all users of the new room Status Engine API is called •
248
Creates a status event for room creation
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Room Infrastructure
8.
2006/Q2
At each extension point during the room creation process, the extension framework calls the extensions defined in the template to enable the connection of other back-end systems and to add additional functionality to the new room. Extension points and extensions are discussed in a later unit.
© 2006 SAP AG. All rights reserved.
249
Unit 9: Collaboration Room Infrastructure
EP130
Lesson Summary You should now be able to: • Describe the Collaboration Room Infrastructure
250
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Unit Summary
Unit Summary You should now be able to: • Describe the Collaboration Room Infrastructure
2006/Q2
© 2006 SAP AG. All rights reserved.
251
Unit Summary
252
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 10 Collaboration Room Unit Overview This unit discusses the Collaboration Room API in detail.
Unit Objectives After completing this unit, you will be able to: • • •
Create and manipulate room objects using the API Check room usage information using the API Find the most and least used rooms using the API
Unit Contents Lesson: Collaboration Rooms.................................................254 Exercise 11: Working with the Collaboration Room API...............261
2006/Q2
© 2006 SAP AG. All rights reserved.
253
Unit 10: Collaboration Room
EP130
Lesson: Collaboration Rooms Lesson Overview Lesson Objectives After completing this lesson, you will be able to: • • •
Create and manipulate room objects using the API Check room usage information using the API Find the most and least used rooms using the API
Business Example Your employer has asked for room usage information for auditing purposes. Each project is to receive a weekly report that shows what users have joined or left project rooms, or have changed roles within a room. You decide that the best way to implement this is using the room event mechanism of the IRoom interface.
Features of the Rooms API The collaboration room API can be used to implement functionality that goes beyond that of the iViews delivered with the collaboration features of NetWeaver Portal. The API gives access to room manipulation functions and hides the details of room data storage in the PCD, UME and using the repository framework. The API is in the set of Java packages that have com.sap.ip.collaboration.room.api as their common root. The main classes used for room creation and manipulation are in the root package com.sap.ip.collaboration.room.api. Rooms objects are accessed using the KM room service, which is retrieved in the following manner:
IRooms roomsAPI = (IRooms) ServiceFactory.getInstance(). getService( IRooms.KM_SERVICE_ID );
It can also be accessed as a portal service instead of a KM service (code samples below show how to do this). The IRooms object contains methods that pertain to all rooms in the system, such as searching rooms, testing room existence, retrieving room roles for users and creating new rooms. The IRoom (singular) object represents a single room object and allows manipulation of that room. The IRooms.createRoom() method takes an IRoomInfo argument, so it is first necessary to create such an object and fill it with the information describing the room to be created:
254
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Rooms
IRoomInfo theRoomInfo = roomsAPI.getRoomCreationInfo(); theRoomInfo.setName("TheRoomName"); theRoomInfo.setDescription("This is the room description"); theRoomInfo.setOwnerId(request.getUser().getUniqueID()); theRoomInfo.setTemplateName("SAP_Standard_Template");
In addition to this, each room is based on a room template, and so this must be specified as well:
ITemplate template = roomsAPI.getRoomTemplate("SAP_Standard_Template");
Role information is then supplied using the template, since roles are defined by the template:
IRoomRole adminRole = template.getRoomRole("Admin"); // IUser object 'aUser' must be defined theRoomInfo.addUserToRole( aUser, adminRole );
Finally, room category information used to classify the room must be supplied, and the room can be created:
// String 'aCategoryName' must be valid category name IRoomCategory category = roomsAPI.getRoomCategoryFactory().getRoomCategory( aCategoryName ); IRoomCategory categories[] = new IRoomCategory[] { category }; theRoomInfo.setCategories( categories ); IRoom theRoom = roomsAPI.createRoom( theRoomInfo, false );
When executing the code above, you may notice that the final operation (createRoom) takes longer than the others. This is because the IRooms object needs to do a lot of processing, including setting up PCD, UME and repository framework information.
2006/Q2
© 2006 SAP AG. All rights reserved.
255
Unit 10: Collaboration Room
EP130
The IRoomInfo object provides the method validate() that will check for missing or inconsistent data in its instance fields. This check is done automatically when IRooms.createRoom() is called. Creation will occur only if this call does not fail. Developers using the API may also use this method to perform a consistency check before calling IRooms.createRoom(). In order to retrieve a room that already exists, use the IRooms.getRoom() method:
// String 'anID' must contain the ID of a room that exists. IRoom aRoom = roomsAPI.getRoom( anID );
Beyond these basic operations, the IRooms object has methods to: • • • • • •
create room roles delete a room check if a room exists (using an ID) retrieve all rooms that a user belongs to retrieve the least visited rooms retrieve the most visited rooms
The IRoom object allows you to perform the following operations on a single room: • • • • • • • •
retrieve and set room info such as the room categories, name, creation date and description retrieve and set room roles get the ID of a room lock and unlock a room hide and unhide a room test user membership in a room retrieve room usage information retrieve room status events based on definable criteria
The IRoomInfo object provides a snapshot of an existing room's settings and can also be used to create a new room. These objects do not contain portal-related information like worksets and pages, nor do they contain room content such as documents or other business objects. This object also provides a field validation method, validate(), which can be invoked prior to calling IRooms.createRoom() to check for missing or inconsistent information. Finally, this object is also passed to room extensions to provide them with information about the room.
256
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Rooms
The IRoomPrincipals interface provides access to the user-related functionality of a room instance, such as changing user role assignments. All calls to changing methods in this interface will change only the snapshot in memory, and no existing room is affected until IRoom.setRoomUsers(IRoomUsers, boolean) is called. Like in a transactional environment, this prevents the room from having inconsistent or non-final states at certain points in time. An instance of the IRoomPrincipals interface is also passed to room extensions at certain extension points to provide a set of affected user role assignments to the extension (for example, added room users or removed room users).
public void changeUserRoles() throws RoomInstantiationException, UMException { //Get the Rooms 6.0 API Portal Service IRooms roomsAPI = (IRooms) PortalRuntime.getRuntimeResources().getService( IRooms.PORTAL_SERVICE_ID); //Get a Room IRoom room = roomsAPI.getRoom( aRoomName ); //Get the initial role of the room IRoomRole newRole = TemplateDataFactory.createRoomRole(room.getInitialRoleName()); //
Get the Room Users
IRoomUsers roomUsers = room.getRoomUsers();
IUser
com.sap.security.api.IUser newUser = UMFactory.getUserFactory().getUserByLogonID(aUserID); roomUsers.addUserRole(newUser.getUniqueID(), newRole); String[] userIds = roomUsers.getAllUsers(); //iterate over all room users for (int i = 0; i < userIds.length; i++) { IRoomRole[] userRoles = roomUsers.getUserRoles(userIds[i]); //... do something with the user & apos;s roles }
//Apply all changes to the Room and send no notification emails room.setRoomUsers(roomUsers, false); } }
An object of type IRelationManager can be retrieved using the IRooms.getRelationManager() method. This interface allows the creation and removal of relations between rooms, and also the retrieval of rooms related to a room in question. A relation between rooms is represented as a link in the end user's UI to allow easy navigation between the related rooms.
2006/Q2
© 2006 SAP AG. All rights reserved.
257
Unit 10: Collaboration Room
EP130
import java.util.List; import com.sap.ip.collaboration.room.api.IRooms; import com.sap.ip.collaboration.room.api.relman.IRelationManager; import com.sapportals.portal.prt.runtime.PortalRuntime; import com.sapportals.wcm.repository.ResourceException;
public void demonstrateRelationOfRooms() throws ResourceException { String sourceRoomId = "4711"; String targetRoomId = "4712"; //Get the Rooms 6.0 API
Portal Service
IRooms roomsAPI = (IRooms) PortalRuntime.getRuntimeResources().getService( IRooms.PORTAL_SERVICE_ID); //Get the RelationManager IRelationManager relMan = roomsAPI.getRelationManager(); //Retrieve a list of possible relation types List types = relMan.getAllAssociationIds(); //Relate two rooms with the first available relation type relMan.relateRoom(sourceRoomId, targetRoomId, (String) types.get(0)); //Search for target rooms of room "4711" List targetRooms = relMan.getRelatedRoomsFromRoom(sourceRoomId, (String) types.get(0)); String roomId = (String) targetRooms.get(0); //roomId should be "4712" now //delete relation relMan.unrelateRoom(sourceRoomId, targetRoomId, (String) types.get(0)); }
Room status events can be retrieved from the IRoom object using the getRoomEvents() method. Events may be retrieved according to criteria passed as parameters to this method. These criteria are • • • •
258
a timestamp parameter, which is used to retrieve events that occurred after the given value a RoomStatusAction parameter (array parameter), used to retrieve events only of the given type a user ID parameter (array parameter), used to retrieve events generated by the specified user a maximum result size
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Rooms
//imports for Collaboration Rooms import com.sap.ip.collaboration.room.api.IRoom; import com.sap.ip.collaboration.room.api.IRooms; import com.sap.ip.collaboration.room.api.IRoomStatusEvent; import com.sap.ip.collaboration.room.api.RoomStatusAction; import com.sap.ip.collaboration.room.api.Exceptions.RoomInstantiationException;
//imports for Portal import com.sapportals.portal.prt.runtime.PortalRuntime;
public void retrieveUserChangeEvents() throws RoomInstantiationException { //Get the Rooms API Service IRooms roomsAPI = (IRooms) PortalRuntime.getRuntimeResources().getService( IRooms.PORTAL_SERVICE_ID); //Get a room IRoom room = roomsAPI.getRoom("4711"); // get all user related status events for the room // retrieve all events since creation of room // for all users // retrieve maximum of 50 events IRoomStatusEvent[] roomEvents = room.getRoomEvents( 0, new RoomStatusAction[] { RoomStatusAction.ROOM_ADD_USER, RoomStatusAction.ROOM_REMOVE_USER, RoomStatusAction.ROOM_CHANGE_USER_ROLE }, null, 50); for (int i = 0; i < roomEvents.length; i++) { // process events
// ...
// for instance: print message
System.out.println(roomEvents[i].getMessage()); } }
2006/Q2
© 2006 SAP AG. All rights reserved.
259
Unit 10: Collaboration Room
EP130
In order to compile applications that make use of these API calls, you will need to include the appropriate JAR files in your NetWeaver Developer Studio Project. The libraries you will need will vary between applications, but all JAR files used for collaboration development can be found in your server's installation directory under • •
...irj\servlet_jsp\irj\root\WEB-INF\portal\portalapps\com.sap.netweaver.coll.shared\lib, and ...\com.sap.netweaver.coll.shared.ui\lib
If you have followed the directions for setting up a development environment for KMC development in Unit 2, you should already have the JAR files contained in these folders in a separate folder for easy inclusion in your projects. Finally, runtime information must be included in the portalapp.xml descriptor when deploying an application that makes use of the room API functionality. This information belongs in the application-config section of the portalapp.xml descriptor, and is similar (but not identical) to the 'SharingReference' information used in other KMC components.
... ... ... ...
260
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Rooms
Exercise 11: Working with the Collaboration Room API Exercise Objectives After completing this exercise, you will be able to: • Create a collaboration room using the Collaboration Room API • Retrieve the set of least used rooms • Add a relation between two rooms
Business Example You have been asked to develop a set of iViews for specialized tasks using collaboration rooms. These iViews are to be used by room administrators to make custom creation of rooms, retrieval of room usage statistics and establishment of room relations easy.
Task 1: Develop a simple iView that creates a collaboration room. The user making the request should be the administrator of the room. Use the first template that is available. 1.
Implement the doContent method of the iView. Don't forget to modify the portalapp.xml file to include the reference to the collaboration libraries.
Task 2: Develop an iView with the following characteristics
2006/Q2
1.
Displays the least used rooms in the system, ordered ascending by number of visits. Output the number of visits to the room, the room ID and the name of the room. Show a maximum of 50 rooms and include all rooms, regardless of the time of visit.
2.
Adds a relation between two rooms that you have previously created with the iView from the first exercise above. Use the first association ID that is returned by the call to getAllAssociationIds. Check to see if the relationship creation worked by retrieving the target room using the relationship manager and the source room.
© 2006 SAP AG. All rights reserved.
261
Unit 10: Collaboration Room
EP130
Solution 11: Working with the Collaboration Room API Task 1: Develop a simple iView that creates a collaboration room. The user making the request should be the administrator of the room. Use the first template that is available. 1.
Implement the doContent method of the iView. Don't forget to modify the portalapp.xml file to include the reference to the collaboration libraries. a)
The doContent method might look similar to this: public void doContent( IPortalComponentRequest request, IPortalComponentResponse response) { this.response = response; try { IResourceContext ctx = getResourceContext(request);
IRooms roomsAPI = (IRooms) ServiceFactory.getInstance().getService( IRooms.KM_SERVICE_ID); printNeatly("Found IRooms object: " + roomsAPI);
IRoomInfo theRoomInfo = roomsAPI.getRoomCreationInfo(); theRoomInfo.setName("TheRoomName"); theRoomInfo.setDescription("This is the room description"); theRoomInfo.setOwnerId( request.getUser().getUniqueID() ); theRoomInfo.setTemplateName("SAP_Standard_Template");
ITemplate template = roomsAPI.getRoomTemplate("SAP_Standard_Template"); IRoomRole adminRole = template.getRoomRole("Admin"); theRoomInfo.addUserToRole(request.getUser().getUniqueID(), adminRole ); IRoomCategory category = roomsAPI.getRoomCategoryFactory().getRoomCategory("default_categor IRoomCategory categories[] = new IRoomCategory[] { category }; theRoomInfo.setCategories(categories);
Continued on next page
262
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Rooms
IRoom theRoom = roomsAPI.createRoom(theRoomInfo, false ); printNeatly("Room created: " + theRoom.getId() );
printNeatly( "Room retrieval: " + roomsAPI.getRoom(theRoom.getId()) );
} catch (Throwable e) { outputFormattedError(e); } }
Task 2: Develop an iView with the following characteristics 1.
Displays the least used rooms in the system, ordered ascending by number of visits. Output the number of visits to the room, the room ID and the name of the room. Show a maximum of 50 rooms and include all rooms, regardless of the time of visit. a)
A simple method to output this information in an iView might look like this:
private void findLeastUsedRooms(IPortalComponentRequest request) throws WcmException, RoomInstantiationException { IRooms roomsAPI = getRoomsService(); IRoomUsage[] usage = roomsAPI.getLeastVisitedRooms(50, 0); for (int i = 0; i < usage.length; i++) { IRoom room = roomsAPI.getRoom( usage[i].getRoomId() ); response.write( usage[i].getVisits() + " " + usage[i].getRoomId() + " " + room.getName() + " "); } }
Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
263
Unit 10: Collaboration Room
2.
EP130
Adds a relation between two rooms that you have previously created with the iView from the first exercise above. Use the first association ID that is returned by the call to getAllAssociationIds. Check to see if the relationship creation worked by retrieving the target room using the relationship manager and the source room. a)
A simple method, which could be used in an iView's doContent method, might look like this:
private void addRelationBetweenRooms(String srcRoomID, String destRoomID) throws WcmException, RoomInstantiationException { IRooms roomsAPI = getRoomsService(); IRelationManager mgr = roomsAPI.getRelationManager(); List assocIDs = mgr.getAllAssociationIds(); String theID = (String) assocIDs.get(0); mgr.relateRoom( srcRoomID, destRoomID, theID);
// Check to see if relationship has been established Map map = mgr.getRelatedRoomsFromRoom( srcRoomID );
// Map contains association ID -> room ID mapping Object o = map.get( theID ); if( o != null ) { printNeatly("Found related room: " + o ); } else { printNeatly("Relation not found."); } }
264
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Rooms
Lesson Summary You should now be able to: • Create and manipulate room objects using the API • Check room usage information using the API • Find the most and least used rooms using the API
2006/Q2
© 2006 SAP AG. All rights reserved.
265
Unit Summary
EP130
Unit Summary You should now be able to: • Create and manipulate room objects using the API • Check room usage information using the API • Find the most and least used rooms using the API
266
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 11 Extensions Unit Overview Collaboration Room extensions provide a flexible and non-intrusive method of integrating components in the Collaboration Room infrastructure. The concepts behind this integration and the details of using the API are covered within this unit.
Unit Objectives After completing this unit, you will be able to: •
Develop your own extensions
Unit Contents Lesson: Extensions.............................................................268 Procedure: Developing an Extension ....................................278
2006/Q2
© 2006 SAP AG. All rights reserved.
267
Unit 11: Extensions
EP130
Lesson: Extensions Lesson Overview An extension for room or room part templates is a program that controls the storing and obtaining of data for rooms or room parts. The Extensions API is introduced within the context of room life cycles. We will also discuss the main points of integration (room events) and the details of developing a custom extension.
Lesson Objectives After completing this lesson, you will be able to: •
Develop your own extensions
Business Example Your project has asked you to develop a simple extension that logs all member list changes of a room for auditing purposes. For example, if an employee is added or removed from a room, this should be written to a permanent log file that can be archived.
Room Extensions During their life cycle, rooms and room parts pass through defined points like the creation or deletion of the room, the change of the room owner or the adding of a room part to the room. Such points in the lifecycle of a room or room part can be used to plug in and execute custom code. This code can be written according to company-specific needs. It is called an extension and the points in the lifecycle are called extension points. The purpose of extensions is to allow flexible functional extensibility of collaboration rooms. This aids in the integration of non-standard systems at customer sites and allows customers to add custom Java coding without changing SAP-delivered code. This custom code will then also not be overwritten when applying a patch or hot fix to the portal. The figure below illustrates what role extensions play in the standard delivery of KMC in NetWeaver Portal and how they are used to integrate other systems. In this case, extensions are used in order to perform actions in both the KM repository hierarchy as well as a BW backend system. The timeline across the top of the diagram shows a simplified lifecycle of a room, with examples of events that can be handled by an extension.
268
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Extensions
Figure 118: Room Lifecycle and Extensions
Technically, an extension is a portal service that adds functionality to virtual rooms. It defines a set of input and output parameters. The core functionality of an extension resides in the method that computes the output from the given input.
Figure 119: Extension Input and Output
A simple example of an extension is the concat extension that is provided by SAP. This extension takes two strings as input and returns the concatenation of those two strings as its output. This extension does not communicate with any backend systems and therefore also does not make use of any transactional functionality of extensions (discussed below). This extension, however, is still often very useful in realistic scenarios that require the manipulation of strings, such as the creation of folders in backend systems. Extensions Provided by SAP
2006/Q2
© 2006 SAP AG. All rights reserved.
269
Unit 11: Extensions
EP130
Extensions Provided by SAP Id
Category
Description
cmRoomExtensionSP2FP
room
Creates, handles, and deletes Content Management workspaces for room and roomparts. Also organizes the entry points to allow copy and move activities between the workspaces of a room.
roomPropertyReader
room
Exposes properties from the system parameter ROOM_INFO
roompartPropertyReader
room
Exposes properties from the system parameter ROOM-PART INFO.
concat
common
Concatenates two strings.
configReader
common
Exposes properties of configurables in the configuration framework
The following table gives an overview of some of the extension points that are available and the system parameters that are added to the context when these points are reached. Extension Points and System Parameters Added to the Context (not complete) Extension Points and System Parameters Added to the Context (not complete) Extension Point A B
270
Predecessor
ON_CREATE_ROOM ON_ADD_ROOMROLE_TO_ROOM
System Parameter IDs ROOM_INFO
A
© 2006 SAP AG. All rights reserved.
ROOM_INFO ADDED_ROOMROLE_TO_ROOM
2006/Q2
EP130
Lesson: Extensions
Extension Point C
ON_ADD_USERS_ TO_ROOMROLES
Predecessor A,B
System Parameter IDs ROOM_INFO ADDED_USERS_TO_ ROOMEROLES
D
ON_SET_OWNER_
A
OF_ROOM
ROOM_INFO OLD_OWNER_OF_ROOM NEW_OWNER_OF_ROOM
E
ON_AFTER_CREATE_ROOM
F
ON_CREATE_ROOMPART
A, B, C, D
ROOM_INFO ROOMPART_ID ROOMPART_TEMPLATE_ID ROOMPART_INFO
G
ON_ADD_ROOMPART_
A, B, C, D, E, ROOM_INFO ROOMF PART_INFO
TO_ROOM H
ON_REMOVE_ROOMPART_
A, B, C, D, E, ROOM_INFO ROOMF, G PART_INFO
FROM_ROOM
I
ON_DELETE_ROOM- F PART
ROOMPART_ID ROOMPART_ TEMPLATE_ID ROOMPART_INFO
J
ON_BEFORE_DELETE_
A, B, C, D, E
ROOM_INFO
ROOM K
ON_REMOVE_USERS_ FROM_ROOMROLES
2006/Q2
A, B, C
ROOM_INFO REMOVED_USERS_FROM_ROOMROLES
© 2006 SAP AG. All rights reserved.
271
Unit 11: Extensions
EP130
Extension Point L
ON_REMOVE_ROOMROLE_
Predecessor A, B
System Parameter IDs ROOM_INFO REMOVED_ROOMROLE_FROM_ROOM
FROM_ROOM M ON_DELETE_ROOM
A, B, C, D, E, ROOM_INFO J, K, L
N
ON_LOCK_ROOM
A, B, C, D, E
O
ON_UNLOCK_ROOM
A, B, C, D, E, ROOM_INFO N
ROOM_INFO
Planning the dataflow of an extension during design time involves configuring a mapping between context parameters and extension input and output parameters. The mapping determines the sources of the input parameter values and the destination of the output parameter values. The mapping is performed by a room template creator in the template administration.
Figure 120: Parameter Assignment in the UI
Note: You will find the extension administration functions in the portal under Content Administration -> Collaboration Content -> Room Template Administration. From there, it is possible to edit templates and add, remove and configure extensions as appropriate. The set of parameters in the template administration includes constants, external parameters and output parameters of extensions. While the mapping of a constant directly assigns the value, the mapping of external parameters or extension output
272
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Extensions
generates a reference to a variable that is filled at run time, e.g. when the room or room part is created. There are also system parameters that are handled internally and therefore are not displayed in the UI. • • • •
Constants are fixed by the template creator at design time. The values are offered in a drop down list box that is filled by a value set provider. System parameters are contributed by the room. A example is the roomInfo object. External parameters are defined at design time, but the value is filled in manually at run time. The user who creates a room is prompted for the value. Extension output can be used as input for another extension.
The availability of a parameter depends on the extension point. For example, the system parameter NEW_OWNER_OF_ROOM is available only when the extension point ON_SET_OWNER_OF_ROOM is processed. Second, the availability of a parameter may depend on another extension that must execute before and deliver the value as an output parameter. Because of this dependency, it is possible to configure deadlocks. Unfortunately a deadlock causes no exception at template creation, the error occurs at room- or room part creation. For the extension developer as well as for the template creator therefore it is important to plan and test the extension usage.
Figure 121: Deadlocks
2006/Q2
© 2006 SAP AG. All rights reserved.
273
Unit 11: Extensions
EP130
Figure 122: Chaining Extensions - Mapping Plan Example
The above graphic gives an example of a parameter-mapping plan. The template creator wants the room to create a document folder that should be named "Documents of %s". At "%s" the creator wants to have the name of the room the folder belongs to. The creator uses the RoomPropertyExtension to extract the room name from the system parameter RoomInfo. The Concat extension allows concatenating the room name and the string constant "Workspace of". The result is given to the CmRoomExtension, which creates the workspace and outputs the path that is mapped to the start_uri of an iView. All assignments are performed at the same extension point. When an extension point is processed, the validate method of all extensions is called first. If one extension fails, the processing of the extension point terminates on error. If all extensions can validate, the process method is called in a second step. If one extension fails to process, all extensions are rolled back. Otherwise, all commit. Implementing transactions is discussed in more detail in the following section. Value set providers are used to define the allowed values for a dedicated input parameter. They can be used to show drop-down list boxes in the UI or to validate user input.
Introduction to Room Extensions
Extension API The extension API is located in the com.sap.netweaver.coll.shared.api.extension package. The main interface for extension implementation is the IExtension interface. The class that implements this interface is responsible for managing the input and output parameters, as well as the processing of those parameters
274
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Extensions
to calculate the output parameter. In addition to the methods for handling the processing and the parameters, there are three methods that add transactions to extensions. Methods, arguments and return types Methods, arguments and return types Return type Method Name and Arguments void commit(IExtensionPoint extension, IExtensionContext context)
Description Method called by the extension processor when no error occured during processing and all changes are finalized.
IExtensionPoint[] getExtensionPoints()
Lists the extension points the extension is able to handle.
IParameterInfo[] getInputParameterInfos(IExtensionPoint point)
Lists information for all input parameters the extension needs in order to to process an extension point.
IParameterInfo[] getOutputParameterInfos(IExtensionPoint point)
List information for all output parameters the extension delivers after processing an extension point.
IExtensionResult process(IExtensionPoint extension, IExtensionContext context)
Method called by the extension processor when an extension point is reached and the extension needs to be processed.
void rollback(IExtensionPoint Method called by the extension, extension processor IExtensionContext when an error occured. context) void validate(IExtensionPoint extension, IExtensionContext context)
2006/Q2
© 2006 SAP AG. All rights reserved.
Method called by the extension processor to validate that the extension can be processed.
275
Unit 11: Extensions
EP130
In addition to implementing this interface, an extension class will extend the com.sap.ip.collaboration.core.api.fwk.portal.GenericService class. When an extension point is processed, first the validate method of all extensions is called. If one extension fails, the processing of the extension point terminates on error. If all extensions can validate, the process method is called in a second step. If one extension fails to process, all extensions are rolled back; otherwise, all commit. •
validate() –
•
Extension takes the input parameters from the context and throws an exception if they are not consistent – Nothing should be processed, only validate the parameters – The validation also may check the availability of a used back end or a required configurable – Must not be implemented, but can cause a high performance effort because avoidable errors must be rolled back over all extensions involved in an extension point process() – – –
•
Extension takes the input parameters from the context Processes them and returns the output parameters as the result Everything processed in this method must be reversible, for example, if the extension deletes something, it should copy it to a recycler or create a backup – The extension fills the parameter directly to the context and removes it in the rollback method rollback() – – –
•
Provided with the same context as the process method May be enriched with objects created during process Task of the rollback is to undo everything of the process method, for example, created objects are deleted, and deleted objects are restored, recycled, or recreated commit() – – – –
276
Finalizes the execution of the extension It is not allowed to do any processing The extension must have fulfilled its purpose, even if commit would not be called Removes backups provided for the rollback that are no longer useful
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Extensions
Developing an Extension Caution: There is currently no wizard support in NetWeaver Developer Studio for developing room extensions. Because of this, and because of the relative complexity of extension projects (and other KMC projects), it is important to pay attention to detail when executing the manual process for setting up and deploying an extension project.
2006/Q2
© 2006 SAP AG. All rights reserved.
277
Unit 11: Extensions
EP130
Developing an Extension 1.
Set up the project •
Create a portal project, as you would when developing any other KMC component or application.File -> New -> Other -> Portal Application -> Create a Portal Application Project Add coll.shared.extension_api.jar to the classpath. Make sure you have taken this library from your portal installation, as covered in the introductory unit. You will need other JARs in your classpath, depending on your application. Add the ServicesReference to your portalapp.xml. A portalapp.xml for a complete, simple extension might look like this
•
•
...
•
Because the extension is a portal service, a service entry in the portalapp.xml file of the project is required. The service name can be chosen freely as long as it fulfils the Java naming conventions.
•
2.
For at least one service in a portalapp.xml file the generic_classloader_registration must be activated, and there must be a generic_service_key defined which can be a GUID, the class name or anything else that is unique. The generic_classloader_registration entry is very important, especially if you would like to use the ResourceBundles utility class that is part of the KMC API (not java.util.ResourceBundle). If this entry is not activated for at least one service in the portalapp.xml file, ResourceBundles usage will not work.
Configure the extension The development project containing the extension must also deploy a Configuration Framework based configurable to the extension registry, which is located in the configuration path System Administration -> System Configuration -> Collaboration -> Extension. In this configurable, the extension id is defined. A common choice is to take the name of the class for the id. The property service is a combination of the par file name of your project plus the service name defined in the file portalapp.xml. Caution: Please note that the par file name and the service name may differ from the package name and the class name. It is a common mistake to use the package name and the class name here. Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
279
Unit 11: Extensions
EP130
In your NetWeaver Developer Studio project, this configurable will be under src.config/install/data/collaboration/extension/registry/. This is a configurable just like any other KMC configurable, and so it follows the same naming standards. For instance, since our extension has the ID “MyDemoExtension”, the configurable object will be located in src.config/install/data/collaboration/extension/registry/_my_demo_extension.co.xml. Notice that capital letters have been replaced by lowercase letters preceded by an underscore. The contents of this file will look like this:
value="MyDemoExtension"/>
value="DemoExtension.MyDemoExtension"/>
The configurable additionally defines a category, which must be “room” for room related extensions or “common” for unspecific extensions that are used in the room. An extension is room related if it accesses the Room API. For example, the “concat” extension is not room related, because it just concatenates two strings and does not access the Room API. There is also an active flag in the configurable that is used to disable the extension. Disabling should be handled with care, because it corrupts templates using this extension. Early versions of the room do not validate the templates, so that there will be exceptions if they are used. Later versions (EP 6.0 SP10 or higher) validate the templates so that they are no longer used. 3.
Create the Java class An extension runs as a portal service and therefore must implement the IService interface that is documented in the PRT User Guide. For simplification the extension can inherit the IService implementation from the GenericService class, which is part of the KM. The GenericService applies the attributes generic_service_key and generic_classloader_registration from the portalapps.xml. The class loader registration is required to use the resource bundles the extension needs to be displayed via name and description in the UI (see 4). To further implement the extension, an IExtensionBuilderFactory provides specific objects like IParameterInfo and IExtensionResult. In the extension class, this factory is retrieved from the extension runtime: Continued on next page
280
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Extensions
import com.sap.netweaver.coll.shared.api.extension.IExtensionBuilderFactory;
public class SampleExtension extends GenericService implements IExtension
{ private IExtensionBuilderFactory extensionFactory = (IExtensionBuilderFactory)ExtensionRuntime.getFactory();
To get more information about extension objects, methods and parameters consult the Java Documentation of the Interfaces. 4.
Make the extension displayable Because an extension is displayed in the template creation wizard, it needs a resource bundle to translate name and description into the required language.
//id of this service private static final String ID = "MyDemoExtension"; private static final String RESOURCE_BUNDLE = DemoExtension.class.getName(); public String getId() { return ID; } public String getName(Locale locale) { try { return ResourceBundles.getBundle(RESOURCE_BUNDLE).getString("lbl_" + getId(), locale); } catch (Exception e) { return this.getId(); } }
Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
281
Unit 11: Extensions
EP130
public String getDescription(Locale locale) { try { return ResourceBundles.getBundle(RESOURCE_BUNDLE).getString("dsc_" + getId(), locale); } catch (Exception e) { return "Description not available: " + this.getId(); } }
The bundle is located in the same project as the extension. The entries in the bundle file look like this:
lbl_input1=First String lbl_input2=Second String lbl_output=Computed value dsc_input1=First input parameter for test extension dsc_input2=Second input parameter for test extension dsc_output=Output of test extension lbl_MyDemoExtension=The Demo Extension dsc_MyDemoExtension=Desc of The Demo Extension
5.
List the extension points Extension points are steps in the life cycle of a room, where the extension is executed. There is no need for an extension to react on each extension point of a room; it depends on the purpose of the extension, which extension points are useful. For rooms, only the points provided in the class RoomExtensionPoint from the Room API can be used. The extension provides a list of points it can handle. The following code returns all extension points that are available:
public IExtensionPoint[] getExtensionPoints() { return extensionFactory.getExtensionPoints();
Continued on next page
282
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Extensions
}
You can also add them individually:
public IExtensionPoint[] getExtensionPoints() {
IExtensionPoint[] result = { RoomExtensionPoint.ON_CREATE_ROOM, RoomExtensionPoint.ON_DELETE_ROOM,
//... }; return result;
}
6.
List the input and output parameters An extension also defines a list of input- and output parameters. For example, an extension that creates a folder may require a parent path and output a folder id. The parameter list depends on the extension point: if the folder is created in ON_CREATE_ROOM, the mentioned parameters are listed only for that point, while other parameters may be required for other points. For the input parameters of an extension only available parameters can be used. The available parameters divide into two kinds: • •
System parameters are contributed by the room. Template parameters are defined in the template. Only string parameters are allowed.
The sample code shows how the input parameters are defined: The extension uses the extension factory to build up a list of IParameterInfo. All required input parameters must be listed, because only the listed parameters will be available for processing. This also holds for system parameters. It is a common mistake not to list the system parameters. Even if system parameter sounds like something that comes automatically, the listing is definitely mandatory. Continued on next page
2006/Q2
© 2006 SAP AG. All rights reserved.
283
Unit 11: Extensions
EP130
public IParameterInfo[] getInputParameterInfos(IExtensionPoint extensionPoint) { //ON_CREATE_ROOM
if (RoomExtensionPoint.ON_CREATE_ROOM.equals(extensionPoint)) {
IDisplayable parameter1Displayable = extensionFactory.createDisplayable(
PARAMETER1_ID, RESOURCE_BUNDLE, "lbl_" + PARAMETER1_ID, "dsc_" + PARAMETER1_ID);
IParameterInfo[] result = { extensionFactory.createInputParameterInfo( parameter1Displayable,
PARAMETER1.CLASS, VALUE_SET_PROVIDER_ID, OPTIONAL), extensionFactory.createSystemParameterInfo(PARAMETER2_ID, PARAMETER2_CLASS, MANDATORY),
//... }; return result;
}
//ON_DELETE_ROOM
//...
Continued on next page
284
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Extensions
return null;
}
7.
Implement the logic of your extension in the process, validate, rollback and commit methods. Here is an example of a simple process method that executes the same basic logic as the “concat” extension: public IExtensionResult process( IExtensionPoint extensionPoint, IExtensionContext context) throws ExtensionException { trace.debugT("process() called"); //get parameters String value1 = (String) context.getValue(PARAM_INPUT1); String value2 = (String) context.getOptionalValue(PARAM_INPUT2); //process String sum = value1; if (value2 != null) sum = value1 + value2;
//return results IExtensionResult result = extensionFactory.createExtensionResult(IExtensionResult.OK); result.putValue(PARAM_OUTPUT, sum); trace.debugT("result of process(): " + result); return result; }
2006/Q2
© 2006 SAP AG. All rights reserved.
285
Unit 11: Extensions
EP130
Lesson Summary You should now be able to: • Develop your own extensions
286
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Unit Summary
Unit Summary You should now be able to: • Develop your own extensions
2006/Q2
© 2006 SAP AG. All rights reserved.
287
Unit Summary
288
EP130
© 2006 SAP AG. All rights reserved.
2006/Q2
Unit 12 Collaboration Services Unit Overview Collaboration services provide collaboration capabilities for a single person or a group of people. This unit covers the API available for integrating new services into the existing KMC infrastructure.
Unit Objectives After completing this unit, you will be able to: • •
Develop your own Collaboration service Configure a Collaboration service
Unit Contents Lesson: Collaboration Services ...............................................290
2006/Q2
© 2006 SAP AG. All rights reserved.
289
Unit 12: Collaboration Services
EP130
Lesson: Collaboration Services Lesson Overview A collaboration service enables a specific way of collaborating online with other portal users. Custom services can be developed in order to integrate collaboration tools not already integrated in the standard portal product.
Lesson Objectives After completing this lesson, you will be able to: • •
Develop your own Collaboration service Configure a Collaboration service
Business Example You have been asked by your project to integrate your corporate instant messaging solution into the portal collaboration launch pad. Users should be able to see other user's status and initiate discussions with them from the portal. You decide the best way to do this is to develop a custom collaboration service.
Introduction to Collaboration Services A collaboration service enables a specific way of collaborating online with other portal users. Examples of this are sending e-mails, sharing an application or initiating a phone call from the portal UI. Collaboration services can be made available in the collaboration launch pad (CLP), room members lists, user details dialog, or in the context menu for a user or user group. Additional collaboration services can be custom developed.
Collaboration Launch Pad The collaboration launch pad (CLP) provides quick and easy access to collaboration functions from the masthead in the standard portal system.
Figure 123: Collaboration Launch Pad in the Portal Masthead
Configuration may be necessary if the “Collaboration” link is not visible in the portal masthead of a standard portal installation. If this is the case, the framework page being used needs to be modified to include the CLP. To do this, navigate to
290
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Services
Content Administration -> Portal Content and open up the framework page (this is “Default Framework Page” in the standard portal). Edit the properties of the Tool Area of the page and set “Enable Collaboration Launch Pad” to “yes”.
Figure 124: Configuring the CLP to Appear in the Masthead
Clicking on the “Collaboration” link in the masthead will open the CLP. Here, users can be added and removed from a personal list. The Collaboration menu item allows easy access to the services that have been configured for the CLP.
Figure 125: Collaboration Launch Pad User List and Service Selection
2006/Q2
© 2006 SAP AG. All rights reserved.
291
Unit 12: Collaboration Services
EP130
Core Logic The collaboration service uses the ContextContainer to store the users involved in the collaborative activity that the service enables. When an application launches a collaboration service, it creates a container and places the respective users or groups in the container. When a user launches the collaboration service, it retrieves the users or groups from the container and uses them in its application logic.
package sample.collaborationservice; import java.util.ArrayList; import com.sap.netweaver.kmc.people.shared.ctx.ContextContainer; import com.sapportals.htmlb.page.DynPage; import com.sapportals.htmlb.page.PageException; import com.sapportals.htmlb.rendering.IPageContext; import com.sapportals.portal.prt.component.IPortalComponentRequest;
public class SampleCollaborationServicePage extends DynPage {
public void doProcessBeforeOutput() throws PageException { IPageContext pc = getPageContext(); IPortalComponentRequest request = (IPortalComponentRequest) pc.getRequest(); // Use the PortalComponentRequest to create the ContextContainer. ContextContainer container = new ContextContainer(request); try { // Retrieve flat list of UniqueIds of Principals ArrayList peopleIdList = container.getResolvedPeopleList(); // @TODO put your application logic here } catch (Exception e) { throw new PageException(e); } } public void doInitialization() throws PageException { } public void doProcessAfterInput() throws PageException
292
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Services
{ } }
Project Structure and Example NetWeaver Developer Studio projects for collaboration services have a similar structure to other KMC development projects. A basic collaboration service project will consist of: • • • • •
A portal component (AbstractPortalComponent or subclass) that represents the core of the service logic A portalapp.xml that references the portal component (and contains the appropriate ServicesReference A bundle file with key / value pairs for the service's button label and tooltip A dummy portal service (also referenced in the portalapp.xml, with generic_classloader_registration set to “yes” A set of configurable objects located under src.config/install/data/collaboration/properties that contain the Configurable information for registering the service. There are two per collaboration service to allow registration of the service with the CLP as well as with the people renderer control
• For example, a portalapp.xml file for a simple collaboration service called “DemoService” and implemented in the Java class “com.sample.DemoService” would look like this:
In addition to the portal component “DemoService”, this portalapp.xml file references a service “DummyService”. The sole purpose of this service is to register the bundle file, which resides in the project structure along with the sources, with the class loader to allow runtime access to the information contained in the bundle. The configurable for this collaboration service is located in “clp_my_demo_service.co.xml”
294
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Lesson: Collaboration Services
This is the configuration file responsible for registering the service with the CLP. A second file, “people_my_demo_service.co.xml” is identical except for the “name” property, which must be “peopleMyDemoService” to conform with the naming standards for configurable objects, as well as the “javaClass” property, which is set to “com.sap.netweaver.coll.coreui.api.uicommands.UILaunchCommand”. In addition to these configuration files, our sample project contains three Java classes and one bundle: •
• •
•
2006/Q2
DemoService extends PageProcessorComponent - this is the core service class. Since we are using a DynPage, this class will contain only a single method that returns a DemoCollabService DemoCollabService - the service logic resides here DummyService - a dummy service registered in the portalapp.xml file for the sole purpose of making the bundle file contained in the deployable unit (PAR) accessible at runtime DemoServiceBundle.properties - a Java properties file that contains the button label and tooltip for the service
© 2006 SAP AG. All rights reserved.
295
Unit 12: Collaboration Services
EP130
Lesson Summary You should now be able to: • Develop your own Collaboration service • Configure a Collaboration service
296
© 2006 SAP AG. All rights reserved.
2006/Q2
EP130
Unit Summary
Unit Summary You should now be able to: • Develop your own Collaboration service • Configure a Collaboration service
2006/Q2
© 2006 SAP AG. All rights reserved.
297
Course Summary
EP130
Course Summary You should now be able to: • • • • • • • • •
298
Identify which JAR files are relevant for custom development tasks Correctly use the KMC Wizards delivered as part of NetWeaver Developer Studio Use properties to store structured data Define what property, namespace and content filters are used for Develop a simple repository manager and identify requirements and estimate effort for larger repository manager development projects Define what components are available to you for customization in the Flex UI Debug Flex UI configurations Use the collaboration room API to automate room functions such as creation, deletion and invitation Develop room extensions to integrate backend systems with collaboration rooms
© 2006 SAP AG. All rights reserved.
2006/Q2
Feedback SAP AG has made every effort in the preparation of this course to ensure the accuracy and completeness of the materials. If you have any corrections or suggestions for improvement, please record them in the appropriate place in the course evaluation.
2006/Q2
© 2006 SAP AG. All rights reserved.
299