iKnowBase Development Toolkit | ||
---|---|---|
Previous | Next | |
iKnowBase Process Services for Activiti | User Administration |
The iKnowBase Development Toolkit enables you to develop iKnowBase Plugins in your IDE and assemble a customer specific edition of the iKnowBase application including the required plugin changes.
While the development toolkit does not replace the standard iKnowBase declarative development model, it provides the developer with a supplement and alternative.
Developers are strongly encouraged to participate in a workshop with the iKnowBase product development team before starting with the Development Toolkit.
Read the other chapters after “Getting started” for detailed information about iKnowBase plugins and technology.
The Development Toolkit uses the Gradle build system for
Gradle is supported by several of the major IDEs, enabling you to import the Gradle project into the IDE.
Your should already have (or do it now):
The iKnowBase distribution files for development are
The sample-build-root is a complete example of a Gradle setup for plugin development. You may use it as is, or develop your own build based on elements in the sample.
The sample-plugin-projects zip contains a set of technology samples to help you get started developing plugins for iKnowBase.
Start with the sample-build-root to create a build workspace. If you want to add the sample projects, we suggest an extraction directory structure like this:
sample-build-root
sample-plugins
// contents of sample-plugin-projects here
We use
Artifactory
for dependency resolution for both external 3rd party and
iKnowBase artifacts.
The gradle.properties file is by default configured with the required settings for accessing artifactory.
Add your plugin projects here. The file contains examples for including the iKnowBase samples as well as set up your custom plugins.
When adding your own plugins, you need to create the project structure that goes with it. The directory structure depends on the type of plugins you create. Each project should contain a build.gradle file (see next section for build.gradle description).
Example:
For the project definition in settings.gradle:
include 'custom-plugins'
include 'custom-plugins:custom-java-jar-plugin'
include 'custom-plugins:custom-groovy-jar-plugin'
include 'custom-plugins:custom-java-war-plugin'
You need to create the project structure:
sample-build-root
custom-plugins
custom-java-jar-plugin
build.gradle
src
main
java
resources
custom-groovy-jar-plugin
build.gradle
src
main
groovy
resources
custom-java-war-plugin
build.gradle
src
main
java
resources
webapp
We recommend using a build.gradle file per project as shown above. The build.gradle will set up plugin project specifics such as:
For a java (.jar) project:
apply plugin: 'java'
dependencies {
provided "com.iknowbase:iknowbase-webapp:$ikbVersion"
}
For a groovy (.jar) project:
apply plugin: 'groovy'
dependencies {
provided "com.iknowbase:iknowbase-webapp:$ikbVersion"
}
For a java web application (.war) project:
apply plugin: 'java'
apply plugin: 'war'
dependencies {
// use 'providedCompile' instead of 'provided' for war projects
providedCompile "com.iknowbase:iknowbase-webapp:$ikbVersion"
}
// Customized war that will add module source as jar to WEB-INF/lib instead of the usual WEB-INF/classes
// This avoids name collision for war resources with the same name (like "spring.factories") when patching
// with multiple war files
war {
// First we'll remove the main build output from the classpath
classpath = classpath.filter {!(it.name.equals('main'))}
// And then add the module's jar archive
classpath jar
}
See sample projects for relevant build.gradle content.
Include your plugin projects in the dependencies section (NOT in buildscript dependencies!).
- Set db.URL, db.ikbUser and db.ikbPassword to match your existing iKnowBase database repository
Start a command prompt in the sample-build-root.
The first gradle command entered will trigger download of the gradle binaries and iKnowBase dependencies.
To provide a list of build tasks available to you:
gradlew tasks
To list all projects in your build:
gradlew projects
To start the iKnowBase web server with all plugins (that you’ve added to the root project runtime) on localhost port 80:
gradlew ikbRun
You can access the iKnowBase installation at http://localhost and verify that everything is up and running.
Now that you know that the base build is OK, it’s time to import to an IDE and start development.
Note: If you change gradle build scripts (settings.gradle, build.gradle) you may need to re-import / refresh to get the updates in your IDE.
Open the sample-build-root/build.gradle. The IDE will import and setup the project for you.
Eclipse requires additional gradle plugin: https://github.com/spring-projects/eclipse-integration-gradle/. Once installed, import the sample-build-root as a gradle build. After import select all projects and adjust project properties for Gradle: Project > Properties > Gradle: Classpath sorting strategy: As returned by build script
Note: If you skipped “ikbRun” step on the command line, you must run the gradle task “ikbPrepare” before starting.
To start iKnowBase with all plugins from the IDE, add an application run configuration with:
All projects may be assembled using:
gradlew assemble
The resulting jar/war will be generated in
<project dir>/build/libs/
.
When you want to deploy iKnowBase with custom plugins to test/production, you need to create a new patched .war file. The iKnowBase wrapper script (iknowbase.sh|.bat) is recommended for adding assembled plugins to your existing iknowbase-webapp-7.0.4.war.
Given the standard iKnowBase installation directory structure (See Quick installation and upgrade overview ):
iknowbase-7.0.4
// extracted distribution files
production (named runtime directory)
iknowbase.properties
iknowbase.sh
plugins
// all plugins should go here
plugin-1.jar
plugin-2.war
wars
// your new patched .war files should go here
Assemble your new war with
./iknowbase.sh <config> assembleWar <input> <output> <extensions>
:
cd production
./iknowbase.sh iknowbase.properties assembleWar ../iknowbase-7.0.4/wars/iknowbase-webapp-7.0.4.war ./wars/iknowbase-webapp-7.0.4-custom.war ./plugins/*
Custom .war files, like the one you just created, must explicitly be specified in the iKnowBase properties file.
An alternative for .jar plugins when target server is the iKnowBase web server , is using the web.extraClasspath setting instead of patching the .war file. Point it to your jar files and they will be available in the classpath when the server has started.
web.extraClasspath=./plugins/*.jar
Deploy the new iknowbase-webapp war file to you application server. No special requirements.
By using the toolkit, you’ll be able to develop your own as well as include externally developed plugins.
Once developed, a plugin will be assembled to one of two forms:
A .jar plugin contains
and is the typical choice if you do not require additional libraries.
You may still use the .jar plugin if you require additional libraries, but you must then collect all the library .jars yourself when patching the iKnowBase application war.
build.gradle:
apply plugin: 'java' // and/or 'groovy', if you prefer groovy development
dependencies {
provided "com.iknowbase:iknowbase-webapp:$ikbVersion"
}
A .war plugin contains:
and is the typical choice if you need more than what is offered through a .jar.
Note: The content in the resulting plugin .war file will override the existing content in the source iKnowBase .war file when patching.
build.gradle:
apply plugin: 'java' // and/or 'groovy', if you prefer groovy development
apply plugin: 'war'
dependencies {
// use 'providedCompile' instead of 'provided' for war projects
providedCompile "com.iknowbase:iknowbase-webapp:$ikbVersion"
}
// Customized war that will add module source as jar to WEB-INF/lib instead of the usual WEB-INF/classes
// This avoids name collision for war resources with the same name (like "spring.factories") when patching
// with multiple war files
war {
// First we'll remove the main build output from the classpath
classpath = classpath.filter {!(it.name.equals('main'))}
// And then add the module's jar archive
classpath jar
}
Note: All libraries in use by the iKnowBase web application are, due to the current build system, available to your plugin at both compile and runtime. However, all “com.iknowbase” packages except “com.iknowbase.api” are considered internal to iKnowBase and use of these packages are prohibited and without support.
All dependencies are managed in your project’s
build.gradle
file.
The plugin projects will get all libraries distributed through the iKnowBase application with this dependency:
// use one of
provided "com.iknowbase:iknowbase-webapp:$ikbVersion" //for groovy/java
providedCompile "com.iknowbase:iknowbase-webapp:$ikbVersion" //for war (even if you java groovy/java plugin activated)
The project may also bring additional libraries, provided they are not conflicting with the existing libraries.
Additional libraries will automatically be included in the resulting plugin .war file when using the .war plugin.
The iKnowBase application is a java web application based on the Spring Framework (http://projects.spring.io/spring-framework/). Your code will need to be deployed into this application, and can then be used from several points and for several purposes.
The table shows what type of extensions and modifications are available
Extension type | Language |
---|---|
Spring Configuration | Java, Groovy |
Spring Bean | Java, Groovy |
Spring MVC Controller | Java, Groovy |
Spring MVC View | Java, Groovy, Freemarker |
Spring MVC Static plugin-resources | N/A |
Java extension | Java |
Java Activiti extension | Java |
Groovy extension | Groovy |
Freemarker extension | Freemarker |
Log4j configuration | Log4j |
Web application override | Any |
The Spring container keeps track of java beans for the lifetime of the iKnowBase application, and many plugins will need to provide their own beans. To expose your beans, you will need to create and expose a configuration class:
In your source code, this typically looks like this:
The Spring Configuration classes are plain Java/Groovy classes annotated with @Configuration (org.springframework.context.annotation.Configuration). A configuration class allows Spring Bean generation and web application context customizations. The class contains methods annotated with @Bean (org.springframework.context.annotation.Bean) where the resulting bean name is the name of the method and the bean type is the declared and returned object.
To load the Spring Configuration class, create
src/main/resources/META-INF/spring.factories
in your plugin project with:
com.iknowbase.api.server.SpringModule=<YOUR_PACKAGE/YOUR_SPRING_CONFIGURATION_MODULE>
Spring beans are objects managed by the Spring container. Beans are generated using the Spring factory pattern described in the “Spring plugin bootstrap” section above.
The table below shows the iKnowBase specific services that you can @Autowire in your Spring beans, typically in you @Configuration class. Note that these services are not available as resolved method arguments in a Spring Controller.
Service | Description |
---|---|
com.iknowbase.api.contentservices.ContentServicesEngine | iKnowBase Content Services API for accessing the iKnowBase ContentServices engine. |
com.iknowbase.presentationservices.PresentationServicesEngine | iKnowBase Presentation Services API for accessing the iKnowBase PresentationServices engine. |
The services below are available directly for backward compatibility reasons. They can (and should) be accessed through the ContentServicesEngine or PresentationServicesEngine above.
Service | Description |
---|---|
javax.sql.DataSource | DataSource for accessing the iKnowBase Database Repository. |
com.iknowbase.api.contentservices.v2.service.DocumentService | iKnowBase Content Services API for accessing the iKnowBase Content Repository. |
The iKnowBase applications can be configured as described in Installation Guide > Configuration . You may also add your own configuration keys to this set.
The configurations can be injected in the @Configuration’s @Bean methods using @Value-annotation. You pass the values to your actual bean when constructing the bean.:
Configuration option | Default value |
---|---|
@Value(“${JAVA_HOME}”) String javaHome | not set |
@Value(“${JAVA_HOME:#{null}}”) String javaHome | null |
@Value(“${JAVA_HOME:null}”) String javaHome | “null” |
@Value(“${com.iknowbase.pageEngine.contentCacheEnabled:false}”) boolean contentCacheEnabled | false |
@Value(“${thisKeyShouldNotBePresentUseDefault:default_value}”) String thisKeyShouldNotBePresentUseDefault | “default_value” |
If a default value has not been specified, the configuration MUST exist.
The Spring MVC Controller is used to expose your extension at the specified web request path. See the Spring documentation and the provided iKnowBase Development Toolkit samples.
The concept of using a Spring MVC Controller is as follows:
NOTE: DO NOT use the @Controller annotation. Construct your controller bean in the @Configuration class and annotate the Controller itself with @RequestMapping,if you require @RequestMapping support.
Since a Spring MVC Controller is just a regular Spring Bean, you can inject services and configurations as for any @Bean.
When Spring runs your @RequestMapping method, it will automatically pass parameter values to that method. In addition to the default argument resolving available for Spring MVC (like HttpServletRequest, HttpServletResponse, etc), the iKnowBase web application supports it’s own set of services and resolved arguments.
The following table shows the iKnowBase specific services available to you in the Spring configuration and controller classes and where it can be injected.
Service | Description |
---|---|
com.iknowbase.api.contentservices.ContentServicesClient | iKnowBase Content Services Client for accessing the iKnowBase Content Services. |
com.iknowbase.api.presentationservices.PresentationServicesClient | iKnowBase Presentation Services Client for accessing the iKnowBase Presentation Services. |
com.iknowbase.api.presentationservices.client.ActivitiClient | iKnowBase Activiti Client for accessing the Activiti process engine. |
com.iknowbase.api.presentationservices.client.SolrSearchClientProvider | iKnowBase Solr Search Client Provider for accessing the configured Solr Search Clients. |
com.iknowbase.api.presentationservices.client.SpringMvcPageEngineClient | iKnowBase Spring MVC Page Client for accessing the iKnowBase Page Engine. |
Controllers may be annotated with Spring Security annotations if you want to restrict access to a controller method.
Some examples of standard expressions included with Spring Security:
Configuration option | Default value |
---|---|
@PreAuthorize(“isAnonymous()”) | Access as public user |
@PreAuthorize(“isAuthenticated()”) | Access as non-public user |
In addition to the standard Spring Security annotations, the following iKnowBase specific annotations are supported:
Configuration option | Default value |
---|---|
@PreAuthorize(“hasPermission('[ACL_EXTERNAL_KEY]', 'ACL', 'READ')”) | ACL membership and privilege READ |
@PreAuthorize(“hasPermission('[ACL_EXTERNAL_KEY]', 'ACL', 'MODIFY')”) | ACL membership and privilege MODIFY |
@PreAuthorize(“hasPermission('[ACL_EXTERNAL_KEY]', 'ACL', 'DELETE')”) | ACL membership and privilege DELETE |
@PreAuthorize(“hasPermission('executionUser', 'ADMIN')”) | Current effective user has administrator privileges |
@PreAuthorize(“hasPermission('authenticatedUser', 'ADMIN')”) | Real authenticated user has administrator privileges |
executionUser and authenticatedUser will normally be the same, but if an administrator has switched to a different user in the current session, the authenticatedUser will be the administrator and the executionUser will be the switched to user.
Static web resources, such as css, javascript and images, can be included in your plugin project. The resources will be assembled and served from jar files.
src/main/resources/META_INF/resources/plugin-resources
META_INF/resources/plugin-resources
//server/application-root/plugin-resources
Note! The static resources namespace will be shared among all plugins. Be sure to use plugin specific directories for your static content.
Alternatively, static web resources may be served as an additional war project of your choosing, like /custom-resources. The /ressurs is by default taken by the iknowbase-resources. See iknowbase.properties if you need to override this behavior.
Activiti processes can be extended using Execution Listeners , Task Listeners and Service Tasks .
The iKnowBase Repository Model is accessible from task and execution listeners and service tasks, provided is has been mapped in the process definition.
Java or Groovy classes may be used from groovy components you define in iKnowBase Development Studio. This enables you to create reusable components in plugins and access them in both the plugin and the traditional development model.
Log4j configuration files are present under WEB-INF/classes in the iKnowBase application and you may add additional configurations or override configurations. When overriding, make sure the plugin war has the configurations files defined in WEB-INF/classes as files added here take presedence over files found in library files in WEB-INF/lib.
You may also start the iKnowBase web server with a specific log4j configuration by adding the jvm option
-Dlog4j.configuration=file://<your configuration file>
to the run configuration in your IDE.
The iKnowBase application server provides a SolrClient-object for easy access to the search functionality of a Solr server. This is often configured using the installation properties of an installation, but if you need more control of the SolrServer connection, you can use the Development Toolkit to configure the server yourself:
@Bean(name="acmeInternetSearch")
public SolrServer createSolrServer() {
CloudSolrServer cloudSolrServer = new CloudSolrServer("zookeeper.solr.acme.com");
cloudSolrServer.setParser(new XMLResponseParser());
return cloudSolrServer;
}
When the above @Bean is exposed to the application container (through a @Configuration class), iKnowBase will automatically discover it, and use it as the basis of a search connection. The name specified in the @Bean will be used for the search server.
iKnowBase simplifies form development that targets iKnowBase documents with
See sample: sample-plugin-form
To easily convert between an iKnowBase document and a standard Java Bean (Not a Spring Bean), iKnowBase provides annotations for use in the Java Bean that enables automatic conversion and efficient development.
Annotation | Description |
---|---|
@AttributeMapping | For mapping iKnowBase attributes to properties. Processed by the BeanProcessor class. Use on getter methods. |
@Init | For methods that needs to be invoked during initialization of the form backing bean. |
@BindingError | For methods that needs to be invoked after binding and validation of the form backing bean. |
@BeforeBeanToAttributesMapping | For methods that needs to be invoked before a bean is converter to DocumentAttributes. |
@BeforeInsert | For methods that needs to be invoked after conversion to document attributes and before save to iKnowBase repository as new document. |
@BeforeUpdate | For methods that needs to be invoked after conversion to document attributes and before save to iKnowBase repository updating an existing document. |
@AfterLoad | For methods that needs to be invoked after load from iKnowBase repository. |
@AfterInsert | For methods that needs to be invoked after save of new document to iKnowBase repository. |
@AfterUpdate | For methods that needs to be invoked after save of existing document to iKnowBase repository. |
The iKnowBase Presentation Services Form Processor aids with conversion, loading, insert and update of iKnowBase AttributeMapping annotated beans (see previous section). It also provides FreeMarker macros to ease integration with the Java Bean and iKnowBase Metadata.
An iKnowBase Classic Form may now also be configured as an External Form. An External Form supports mapping against a URL path, where the plugin containing the requested form is available.
If you store the External Form reference on the document, the plugin form will be used in generic iKnowBase Classic edit links.
An External Form may also be connected to document types and set as default form to allow using the plugin form on documents that have no specific form registration.
Normal Quicklink and Target integration for forms also applies to an External Form.
You may convert a Clasic Form component between Classic Form and External Form and thus keep the preexisting form GUID used on the documents.
Java based versions of News Article and Admin Form are available in iKnowBase Content Studio and External Form data has been registered. The form is classic by default, but may easily be converted to an External Form supported by Java. See source code for the forms and their required metadata.
The following samples are included when installing the Development Toolkit:
Sample name | Description |
---|---|
sample-plugins:sample-activiti-controllers | Demonstrates using DataSource, DocumentService and ActivitiClient. |
sample-plugins:sample-activiti-process-definitions | Demonstrates a project containing Activiti process definitions. Also demonstrates how to map the iKnowBase RepositoryModel, listeners and service task. |
sample-plugins:sample-activiti-extensions | Demonstrates task and execution listeners for Activiti. Also demonstrates how to use the iKnowBase RepositoryModel. |
sample-plugins:sample-plugin-config | Demonstrates accessing iKnowBase Configuration options. |
sample-plugins:sample-plugin-freemarker | Demonstrates various ways of using freemarker as presentation view technology. |
sample-plugins:sample-plugin-groovy | Demonstrates writing controllers in groovy and use freemarker as presentation view technology as well as various ways of using groovy as presentation view technology. |
sample-plugins:sample-plugin-hello | Demonstrates a very simple controller for a minimal start. |
sample-plugins:sample-plugin-msoffice | Demonstrates using a third party library for generating Excel files. |
sample-plugins:sample-plugin-static-content | Demonstrates using static content, such as css, js and images. |
sample-plugins:sample-plugin-form | Demonstrates developing forms. See form section for details. |
While the samples listed above are focused on demonstration of technology, the iKnowBase distribution includes two complete real life plugins that you may use as reference. The source code is provided alongside the distribution.
Sample name | Description |
---|---|
iknowbase-content-studio | The iKnowBase Content Studio (/cs). |
iknowbase-process-studio | The iKnowBase Process Studio (/ps). |
When importing the iknowbase-plugins project with subprojects in Eclipse, the classpath defaults generated by the eclipse plugin is not correctly ordered.
Resolve the issue with
You may encounter issues when building the gradle project model during import in Eclipse. Adjust your
gradle.properties
file and enable
org.gradle.jvmargs=-Xms128m -Xmx256m
Make sure the property files (*.properties) are located in source tree ‘src/main/resources’ and NOT ‘src/main/java’. Encode all accented characters using unicode notation "\u".
iKnowBase will NOT do any Spring component scanning. To load a Spring controller and expose the methods you need to
NOTE: iKnowBase versions up to and including 6.6 had component scan for the “com.iknowbase.plugin” package. This has been removed and replaced with the spring.factories and @Configuration.
The “ikbPrepare” gradle task downloads and unpacks all required iKnowBase web app resources. If you skipped “ikbRun” step on the command line, you must run the gradle task “ikbPrepare” before starting. “ikbRun” will call “ikbPrepare”.
Previous | Top | Next |
iKnowBase Process Services for Activiti | User Administration |