Create your own import station plugin
To create your own import plugin, you must create a new class that implements the PropertiesProcessor interface:
public interface PropertiesProcessor extends Plugin {
String getName();
String getDescription();
Class<?> getFormBeanClass();
boolean doJob(long executionTaskId, FormProperties formProperties, OKMWebservices webService);
String getAddTaskFormName();
String getEditTaskFormName();
}
Do not forget the tag @PluginImplementation; otherwise, the application's plugin system will not be able to retrieve the new class.
The new class must be loaded into the package com.openkm.processor because the application's plugin system will try to load it from there.
Method descriptions
Method | Return | Description |
---|---|---|
getName() | String |
This method will provide the name of the plugin. |
getDescription() | String |
Detailed plugin description shown below the combo box named "Processor" in the task edit view. |
getFormBeanClass() | Class<?> |
Returns the bean used to store the information of the application form. |
doJob(long executionTaskId, FormProperties formProperties, WsInterface wsInterface) | boolean |
This is the main method of the plugin. |
getAddTaskFormName() | String |
Returns the name of the form used to create properties. |
getEditTaskFormName() | String |
Returns the name of the form used to edit properties. |
Form bean
The plugin must have an associated bean class that is used for setting the plugin's custom properties. These properties will be stored in a map named customProperties.
The Form bean class must extend the FormProperties class.
You can get these property values from the object formProperties in the doJob method. The object formProperties has a field named customProperties.
Restrictions:
- The keys in the map must match the HTML form names.
Sample:
For example, if we want to store a String property named path in this form, the HTML form name must be <input name="path" ...>.
HTML forms
The plugin must have two forms:
- Create task form.
- Edit task form.
They must be located in the src/main/html folder.
We need these forms because each plugin will have its own custom properties.
The naming convention should be: <name_of_plugin>-form.html and <name_of_plugin>-form-edit.html, but they can be any names.
This convention is useful to avoid overriding predefined forms.
Sample:
- Plugin class at src/main/java/com/openkm/processor/ExampleProcessor.class
- Create form at src/main/html/ExampleProcessor-form.html
- Edit form at src/main/html/ExampleProcessor-form.html
These forms will be loaded in the Add Task and Edit Task web screens when the processor combo box is changed.
They should contain necessary HTML and JavaScript code to store and load Processor properties.
In the edit form, for automatic field filling you must use the class="form-control parameter".
For example:
<input type="text" class="form-control parameter" name="userPath">
This will set the parameter userPath into the input with the name "userPath".
Event log
The application has a log feature that provides a complete trace of what happens while processing a task.
Whether to log events is an implementation decision of the plugin designer. We encourage logging every event; however, it is up to the plugin designer to decide.
For this purpose, the class used to log events is ImportStationLogger.
The following methods are available:
Method | Return | Description |
---|---|---|
logOk(long taskExecutionId, String description) | void |
Log an event to indicate that the operation was OK |
logErrorEvent(long taskExecutionId, String description) | void |
Log an event to indicate that there was an error. |
logErrorEvent(long taskExecutionId, String header, Exception e) |
void |
Log an event to indicate that there was an error. This method will log the exception stack trace as the description. The parameter header is used to add a log message to the exception stack trace. |
Example:
long taskExecutionId = ...;
// Mark as ok
ImportStationLogger.logOkEvent(taskExecutionId, "description");
// Mark with errors
ImportStationLogger.logErrorEvent(taskExecutionId, "description of error");
// Mark with error and exception detail
ImportStationLogger.logErrorEvent(taskExecutionId, "header", new Exception("exception"));
Example
This is a sample pom.xml configuration:
You can download the source code from here: import-station-example-plugin.zip
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>copm</groupId>
<artifactId>com</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>example</name>
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<openkm-sdk4j.version>4.1</openkm-sdk4j.version>
<jspf.version>1.0.3.1</jspf.version>
<openkm-import-station-core.version>3.0</openkm-import-station-core.version>
</properties>
<repositories>
<repository>
<id>openkm.com</id>
<name>OpenKM Maven Repository</name>
<url>https://maven.openkm.com</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.openkm</groupId>
<artifactId>import-station-core</artifactId>
<version>${openkm-import-station-core.version}</version>
<classifier>core</classifier>
</dependency>
<!-- Plugin framework -->
<dependency>
<groupId>com.google.code</groupId>
<artifactId>jspf.core</artifactId>
<version>${jspf.version}</version>
</dependency>
<!-- OpenKM SDK -->
<dependency>
<groupId>com.openkm</groupId>
<artifactId>sdk4j</artifactId>
<version>${openkm-sdk4j.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/html</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
ExampleProcessor class:
Description: Imports only files from a specific source folder.
@PluginImplementation
public class ExampleProcessor implements PropertiesProcessor {
@Override
public boolean doJob(long executionTaskId, FormProperties formProperties, OKMWebservices webServices) {
boolean returnValue = true;
File folder = new File((String) formProperties.getCustomPropertiesMap().get(ProcessorConstants.USER_PATH));
if (folder.exists() && folder.isDirectory()) {
for (File file : folder.listFiles()) {
if (file.isFile() && file.canRead()) {
try {
uploadDocument(file, formProperties, webServices);
ImportStationLogger.logOkEvent(executionTaskId, "File uploaded: " + file.getName());
} catch (IOException | UnsupportedMimeTypeException | FileSizeExceededException | UserQuotaExceededException
| VirusDetectedException | ItemExistsException | PathNotFoundException | AccessDeniedException
| RepositoryException | DatabaseException | ExtensionException | AutomationException
| UnknowException | WebserviceException e) {
ImportStationLogger.logErrorEvent(executionTaskId, "Error uploading file" + file.getName(), e);
returnValue = false;
}
}
}
}
return returnValue;
}
private void uploadDocument(File file, FormProperties formProperties, OKMWebservices webServices) throws IOException, UnsupportedMimeTypeException, FileSizeExceededException, UserQuotaExceededException, VirusDetectedException, ItemExistsException, PathNotFoundException, AccessDeniedException, RepositoryException, DatabaseException, ExtensionException, AutomationException, UnknowException, WebserviceException {
String fldPath = formProperties.getObjectProperty(ProcessorConstants.DESTINY_PATH);
String docName = FilenameUtils.getBaseName(file.getName()) + "." + FilenameUtils.getExtension(file.getName());
String fldUuid = webServices.repository.getNodeUuid(fldPath);
// Create document
webServices.document.create(fldUuid, docName, FileUtils.openInputStream(file));
}
@Override
public String getAddTaskFormName() {
return "ExampleProcessor-form.html";
}
@Override
public String getDescription() {
return "This is my custom form";
}
@Override
public String getEditTaskFormName() {
return "ExampleProcessor-form-edit.html";
}
@Override
public Class<?> getFormBeanClass() {
return ExampleFormProperties.class;
}
@Override
public String getName() {
return "ExampleProcessor";
}
}
Bean code. Only stores the user's local path and the OpenKM destination path:
ExampleFormProperties class:
Description:
- Sets the source folder path.
- Sets the target OpenKM folder.
public class ExampleFormProperties extends FormProperties {
/**
* Public constructor.
*
* @param parameterMap
* map with values
*/
public ExampleFormProperties(final Map<String, Object> parameterMap) {
super(parameterMap);
// Add custom properties
addProperty(ProcessorConstants.USER_PATH,
parameterMap.get(ProcessorConstants.USER_PATH) instanceof String[]
? ((String[]) parameterMap.get(ProcessorConstants.USER_PATH))[0]
: parameterMap.get(ProcessorConstants.USER_PATH));
addProperty(ProcessorConstants.DESTINY_PATH,
parameterMap.get(ProcessorConstants.DESTINY_PATH) instanceof String[]
? ((String[]) parameterMap.get(ProcessorConstants.DESTINY_PATH))[0]
: parameterMap.get(ProcessorConstants.DESTINY_PATH));
}
}
ExampleProcessor-form.html
Description:
- Form field source folder.
- Form field target folder.
<div class="form-group">
<label class="control-label col-sm-2" for="userPath">User path:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="userPath"
placeholder="user path" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="destinyPath">Destiny path into OpenKM:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="destinyPath" placeholder="/okm:root/import/" required />
</div>
</div>
ExampleProcessor-form-edit.html
Description:
- Form field source folder.
- Form field target folder.
<div class="form-group">
<label class="control-label col-sm-2" for="userPath">User path:</label>
<div class="col-sm-10">
<input type="text" class="form-control parameter" name="userPath"
value="${userPath}" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="destinyPath">Destiny path into OpenKM:</label>
<div class="col-sm-10">
<input type="text" class="form-control parameter" name="destinyPath" placeholder="/okm:root/import/" required />
</div>
</div>