Creating your own Stack Metadata Adapter ( deprecated )

The StackMetadata class implements the logic that takes control on what is shown into metadata stack - tree nodes on left panel - and their objects ( documents, nodes, folders, records ) on right panel ( browser ).

You can create your own Stack Metadata Adapter.

Conditions:

  • The new Stack Metadata Adapter class must implement the "StackMetadataAdapter" interface.
  • The new Stack Metadata Adapter class must be declared under the package "com.openkm.plugin.stack.metadata".
  • The new Stack Metadata Adapter class must be annotated with "@PluginImplementation".
  • The new Stack Metadata Adapter class must extend of "BasePlugin".

Stack Metadata Adapter interface:

package com.openkm.plugin.stack;

import com.openkm.bean.Document;
import com.openkm.bean.Folder;
import com.openkm.bean.Mail;
import com.openkm.bean.Record;
import net.xeoh.plugins.base.Plugin;

import java.util.List;

public interface StackMetadataAdapter extends Plugin {

    String getName();

    boolean isPropertyGroupHidden(String pgName);

    Folder getProperties(String fldPath);

    List<Folder> getChildren(String fldPath);

    List<Document> getDocumentMetadataChildren(String fldPath);

    List<Record> getRecordMetadataChildren(String fldPath);

    List<Mail> getMailMetadataChildren(String fldPath);

    List<Folder> getFolderMetadataChildren(String fldPath);
}

The new class must be loaded into the package com.openkm.plugin.stack.metadata because application plugins system will try to load from there.

Do not miss the tag @PluginImplementation otherwise the application plugin system will not be able to retrieve the new class.

More information at Register a new plugin.

Methods description

MethodTypeDescription

getName()

String

Return the name shown at plugins table.

isPropertyGroupHidden(String pgName)

boolean Return if metadata fields are hidden.

getProperties(String fldPath)

Folder Return folder properties.

getChildren(String fldPath)

List<Folder>

Return a list of folders.

When folder node is chosen from tree ( left panel ) this method is called to retrieve children folders. These folders are displayed on tree as child nodes.

getDocumentMetadataChildren(String fldPath)

List<Document>

Return a list of documents.

When the folder node is chosen from tree ( left panel ) this method is called to retrieve children documents. These documents are displayed on browser explorer, right panel.

getRecordMetadataChildren(String fldPath)

List<Record>

Return a list of records.

When folder node is chosen from tree ( left panel ) this method is called to retrieve children records. These records are displayed on browser explorer, right panel.

getMailMetadataChildren(String fldPath)

List<Mail>

Return a list of mails.

When folder node is chosen from tree ( left panel ) this method is called to retrieve children mails. These mails are displayed on browser explorer, right panel.

getFolderMetadataChildren(String fldPath)

List<Folder>

Return a list of folders.

When folder node is chosen from tree ( left panel ) this method is called to retrieve children folders. These folders are displayed on browser explorer, right panel.

Example of the Stack Metadata implementation

package com.openkm.plugin.stack.metadata;

import com.openkm.api.OKMPropertyGroup;
import com.openkm.api.OKMRepository;
import com.openkm.api.OKMSearch;
import com.openkm.bean.*;
import com.openkm.bean.form.*;
import com.openkm.core.Config;
import com.openkm.db.bean.KeyValue;
import com.openkm.db.service.KeyValueSrv;
import com.openkm.plugin.BasePlugin;
import com.openkm.plugin.stack.StackMetadataAdapter;
import net.xeoh.plugins.base.annotations.PluginImplementation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

@PluginImplementation
public class ParentChildStackMetadataAdapter extends BasePlugin implements StackMetadataAdapter {

    private static Logger log = LoggerFactory.getLogger(ParentChildStackMetadataAdapter.class);

    @Autowired
    private OKMPropertyGroup okmPropertyGroup;

    @Autowired
    private OKMRepository okmRepository;

    @Autowired
    private KeyValueSrv keyValueSrv;

    @Autowired
    private OKMSearch okmSearch;

    @Override
    public String getName() {
        return "Parent Child Metadata Adapter";
    }

    @Override
    public List<Folder> getFolderMetadataChildren(String fldPath) {
        List<Folder> folderList = new ArrayList<>();

        try {
            // Metadata value level
            if (fldPath.startsWith("/" + Repository.METADATA) && (fldPath.split("/").length - 1) >= 4) {
                String subFolder[] = fldPath.split("/");
                String group = subFolder[2];
                String property = subFolder[subFolder.length - 2];
                String value = subFolder[subFolder.length - 1];

                // In this case we are always in a select with parent Element
                // We need to find de property name, because in property we have the parent value
                if (subFolder.length - 1 > 4) {
                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, group)) {
                        if (formElement instanceof Select) {
                            Select select = (Select) formElement;
                            if (select.getParentElement() != null && !select.getParentElement().isEmpty()) {
                                for (Option option : ((Select) formElement).getOptions()) {
                                    if (option.getValue().equalsIgnoreCase(value)) {
                                        property = select.getName();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                folderList = okmSearch.getFoldersByPropertyValue(null, group, property, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return folderList;
    }

    @Override
    public List<Document> getDocumentMetadataChildren(String fldPath) {
        List<Document> docList = new ArrayList<>();

        try {
            // Case metadata at value level
            if (fldPath.split("/").length - 1 >= 4) {
                String subFolder[] = fldPath.split("/");
                String group = subFolder[2];
                String property = subFolder[subFolder.length - 2];
                String value = subFolder[subFolder.length - 1];

                // In this case we are always in a select with parent Element
                // We need to find de property name, because we have the parent value
                if (subFolder.length - 1 > 4) {
                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, group)) {
                        if (formElement instanceof Select) {
                            Select select = (Select) formElement;
                            if (select.getParentElement() != null && !select.getParentElement().isEmpty()) {
                                for (Option option : ((Select) formElement).getOptions()) {
                                    if (option.getValue().equalsIgnoreCase(value)) {
                                        property = select.getName();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                docList = okmSearch.getDocumentsByPropertyValue(null, group, property, value);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return docList;
    }

    @Override
    public List<Record> getRecordMetadataChildren(String fldPath) {
        List<Record> recordList = new ArrayList<>();

        try {
            // Case metadata at value level
            if (fldPath.split("/").length - 1 >= 4) {
                String subFolder[] = fldPath.split("/");
                String group = subFolder[2];
                String property = subFolder[subFolder.length - 2];
                String value = subFolder[subFolder.length - 1];

                // In this case we are always in a select with parent Element
                // We need to find de property name, because we have the parent value
                if (subFolder.length - 1 > 4) {
                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, group)) {
                        if (formElement instanceof Select) {
                            Select select = (Select) formElement;
                            if (select.getParentElement() != null && !select.getParentElement().isEmpty()) {
                                for (Option option : ((Select) formElement).getOptions()) {
                                    if (option.getValue().equalsIgnoreCase(value)) {
                                        property = select.getName();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                recordList = okmSearch.getRecordsByPropertyValue(null, group, property, value);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return recordList;
    }

    @Override
    public List<Mail> getMailMetadataChildren(String fldPath) {
        List<Mail> mailList = new ArrayList<>();

        try {
            // Case metadata at value level
            if (fldPath.split("/").length - 1 >= 4) {
                String subFolder[] = fldPath.split("/");
                String group = subFolder[2];
                String property = subFolder[subFolder.length - 2];
                String value = subFolder[subFolder.length - 1];

                // In this case we are always in a select with parent Element
                // We need to find de property name, because we have the parent value
                if (subFolder.length - 1 > 4) {
                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, group)) {
                        if (formElement instanceof Select) {
                            Select select = (Select) formElement;
                            if (select.getParentElement() != null && !select.getParentElement().isEmpty()) {
                                for (Option option : ((Select) formElement).getOptions()) {
                                    if (option.getValue().equalsIgnoreCase(value)) {
                                        property = select.getName();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                mailList = okmSearch.getMailsByPropertyValue(null, group, property, value);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return mailList;
    }

    @Override
    public List<Folder> getChildren(String fldPath) {
        List<Folder> folderList = new ArrayList<>();

        try {
            switch (fldPath.split("/").length - 1) {
                case 1: // getting group level
                    for (PropertyGroup pg : okmPropertyGroup.getAllGroups(null)) {
                        // Only represent metadata groups which have some representable object ( select or suggestbox )
                        boolean hasValidChildren = false;

                        for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, pg.getName())) {
                            if (!isPropertyGroupHidden(pg.getName())) {
                                if (!isPropertyGroupHidden(formElement.getName()) && (formElement instanceof Select || formElement instanceof SuggestBox || formElement instanceof CheckBox)) {
                                    hasValidChildren = true;
                                    break;
                                }
                            }
                        }

                        if (hasValidChildren) {
                            Folder folder = new Folder();
                            String path = fldPath + "/" + pg.getName();
                            folder.initMetadata(path, pg.getLabel(),
                                    okmPropertyGroup.getPropertyGroupForm(null, pg.getName()).size() > 0);
                            folderList.add(folder);
                        }
                    }
                    break;

                case 2: // getting property level
                    String grpName = fldPath.substring(fldPath.lastIndexOf("/") + 1);
                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, grpName)) {
                        if (!isPropertyGroupHidden(formElement.getName())) {
                            if (formElement instanceof Select) {
                                Select select = (Select) formElement;
                                // Only draw select with no parent
                                if (select.getParentElement() == null || select.getParentElement().isEmpty()) {
                                    Folder folder = new Folder();
                                    String path = fldPath + "/" + formElement.getName();
                                    folder.initMetadata(path, formElement.getLabel(), false);
                                    folderList.add(folder);
                                }
                            } else if (formElement instanceof SuggestBox || formElement instanceof CheckBox) {
                                Folder folder = new Folder();
                                String path = fldPath + "/" + formElement.getName();
                                folder.initMetadata(path, formElement.getLabel(), false);
                                folderList.add(folder);
                            }
                        }
                    }
                    break;

                case 3: // getting property value first level
                    String subFolder[] = fldPath.split("/");
                    grpName = subFolder[2];
                    String propertyName = subFolder[3];

                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, grpName)) {
                        if (formElement.getName().equals(propertyName)) {
                            if (formElement instanceof Select) {
                                for (Option option : ((Select) formElement).getOptions()) {
                                    Folder folder = new Folder();
                                    String path = fldPath + "/" + option.getValue();
                                    folder.initMetadata(path, option.getLabel(), false);
                                    folderList.add(folder);
                                }
                            } else if (formElement instanceof SuggestBox) {
                                SuggestBox sb = ((SuggestBox) formElement);
                                String sqlFilter = sb.getFilterQuery();

                                // replacing filter parameter, if exist
                                sqlFilter = sqlFilter.replaceAll("\\{0\\}", "");

                                for (KeyValue keyValue : keyValueSrv.getKeyValues(sb.getTable(), sqlFilter)) {
                                    Folder folder = new Folder();
                                    String path = fldPath + "/" + keyValue.getKey();
                                    folder.initMetadata(path, keyValue.getValue(), false);
                                    folderList.add(folder);
                                }
                            } else if (formElement instanceof CheckBox) {
                                Folder folder = new Folder();
                                String path = fldPath + "/true";
                                folder.initMetadata(path, "true", false);
                                folderList.add(folder);
                                folder = new Folder();
                                path = fldPath + "/false";
                                folder.initMetadata(path, "false", false);
                                folderList.add(folder);
                            }
                            break;
                        }
                    }
                    break;

                default: // getting property value for select with parent elements
                    subFolder = fldPath.split("/");
                    grpName = subFolder[2];
                    String pgValue = subFolder[subFolder.length - 1];

                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, grpName)) {
                        if (formElement instanceof Select) {
                            Select select = (Select) formElement;
                            if (select.getParentElement() != null && !select.getParentElement().isEmpty()) {
                                for (Option option : select.getOptions()) {
                                    if (option.getParentValue().equalsIgnoreCase(pgValue)) {
                                        Folder folder = new Folder();
                                        String path = fldPath + "/" + option.getValue();
                                        folder.initMetadata(path, option.getLabel(), false);
                                        folderList.add(folder);
                                    }
                                }
                            }
                        }
                    }
                    break;
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return folderList;
    }

    /**
     * If if a given property or property group is hidden.
     *
     * @param pgName The name of the property or property group.
     * @return Is property group is hidden or not by Config.
     */
    @Override
    public boolean isPropertyGroupHidden(String pgName) {
        boolean isHidden = false;

        for (String metadata : Config.STACK_METADATA_HIDDEN_PROPERTIES) {
            if (pgName.equalsIgnoreCase(metadata)) {
                isHidden = true;
                break;
            }
        }

        return isHidden;
    }

    @Override
    public Folder getProperties(String fldPath) {
        Folder folder = new Folder();

        try {
            String grpName = "";
            String propertyName = "";
            String subFolder[] = fldPath.split("/");

            switch (fldPath.split("/").length - 1) {
                case 1:
                    folder = okmRepository.getMetadataFolder(null);
                    break;

                case 2: // group level
                    grpName = fldPath.substring(fldPath.lastIndexOf("/") + 1);
                    String label = "";

                    for (PropertyGroup pg : okmPropertyGroup.getAllGroups(null)) {
                        if (pg.getName().equals(grpName)) {
                            label = pg.getLabel();
                            break;
                        }
                    }

                    List<FormElement> props = okmPropertyGroup.getPropertyGroupForm(null, grpName);
                    folder.initMetadata(fldPath, label, props.size() > 0);
                    break;

                case 3: // property level
                    grpName = subFolder[2];
                    propertyName = subFolder[3];

                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, grpName)) {
                        if (formElement.getName().equals(propertyName)) {
                            folder.initMetadata(fldPath, formElement.getLabel(), false);
                            break;
                        }
                    }
                    break;

                case 4: // value level
                    grpName = subFolder[2];
                    propertyName = subFolder[3];
                    String value = subFolder[4];

                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, grpName)) {
                        if (formElement.getName().equals(propertyName)) {
                            if (formElement instanceof Select) {
                                Select select = (Select) formElement;
                                // Only select with no parent
                                if (select.getParentElement() == null || select.getParentElement().isEmpty()) {
                                    for (Option option : ((Select) formElement).getOptions()) {
                                        if (option.getValue().equals(value)) {
                                            folder.initMetadata(fldPath, option.getLabel(), false);
                                            break;
                                        }
                                    }
                                }
                            } else if (formElement instanceof SuggestBox) {
                                SuggestBox sb = ((SuggestBox) formElement);
                                String sqlFilter = sb.getFilterQuery();
                                sqlFilter = sqlFilter.replaceAll("\\{0\\}", ""); // replacing filter parameter, if exist

                                for (KeyValue keyValue : keyValueSrv.getKeyValues(sb.getTable(), sqlFilter)) {
                                    if (keyValue.getKey().equals(value)) {
                                        folder.initMetadata(fldPath, keyValue.getValue(), false);
                                        break;
                                    }
                                }
                            } else if (formElement instanceof CheckBox) {
                                folder.initMetadata(fldPath, value, false);
                            }
                            break;
                        }
                    }
                    break;

                default: // value level for select with parent
                    grpName = subFolder[2];
                    String pgValue = subFolder[subFolder.length - 1];

                    for (FormElement formElement : okmPropertyGroup.getPropertyGroupForm(null, grpName)) {
                        if (formElement instanceof Select) {
                            Select select = (Select) formElement;
                            // Only select with no parents
                            if (select.getParentElement() != null && !select.getParentElement().isEmpty()) {
                                for (Option option : ((Select) formElement).getOptions()) {
                                    if (option.getValue().equalsIgnoreCase(pgValue)) {
                                        folder.initMetadata(fldPath, option.getLabel(), false);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    break;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return folder;
    }

}