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 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 plugin system will try to load it from there.
Methods description
Method | Return | Description |
---|---|---|
getName() | String |
This method will provide the name of the plugin. |
getDescription() | String |
Detailed plugin description shown below the combo 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 for creating properties. |
getEditTaskFormName() | String |
Returns the name of the form used for editing properties. |
Form bean
The plugin must have an associated bean class which is used for setting plugin 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 be the same as 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 inside 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 could be any name.
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 is changed.
They should contain necessary HTML and JavaScript code in order to store and load Processor properties.
In the edit form, for automatic filling of fields 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 which enables you to get a complete trace of what is happening while processing a task.
Whether to log events is an implementation decision of the plugin code designer. We encourage logging every event; however, it is the plugin code designer's decision whether to do so.
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 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>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<openkm-sdk4j.version>2.4</openkm-sdk4j.version>
<jspf.version>1.0.3.1</jspf.version>
<openkm-sdk4j.version>2.4</openkm-sdk4j.version>
<openkm-import-station-core.version>1.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>
</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 {
Document doc = new Document();
doc.setPath(formProperties.getObjectProperty(ProcessorConstants.DESTINY_PATH)
+ ImportStationConstants.OKM_REPOSITORY_FILE_SEPARATOR + FilenameUtils.getBaseName(file.getName()) + "."
+ FilenameUtils.getExtension(file.getName()));
// Create document
webServices.createDocument(doc, 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. It only stores the user's local path and the OpenKM destination path:
ExampleFormProperties class:
Description:
- Set source folder path.
- Set OpenKM folder target.
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>