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 ).

To create your own Version number the adapter must create a new class that implements StackMetadataAdapter interface:

package com.openkm.plugin.stack;

import com.openkm.frontend.client.bean.*;
import com.openkm.frontend.client.widget.filebrowser.GWTFilter;
import net.xeoh.plugins.base.Plugin;

import java.util.List;
import java.util.Map;

/**
* */ public interface StackMetadataAdapter extends Plugin { public String getName(); public boolean isPropertyGroupHidden(String pgName); public GWTFolder getProperties(String fldPath); public List<GWTFolder> getChildren(String fldPath, boolean extraColumns, Map<String, GWTFilter> mapFilter); public List<GWTDocument> getDocumentMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace); public List<GWTRecord> getRecordMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace); public List<GWTMail> getMailMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace); public List<GWTFolder> getFolderMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace, String language); }

More information at Register a new plugin.

The new class must be loaded into the package com.openkm.plugin.stack.metadata because application plugin 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.

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)

GWTFolder Return folder properties.

getChildren(String fldPath, boolean extraColumns, Map<String, GWTFilter> mapFilter)

List<GWTFolder>

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, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace)

List<GWTDocument>

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, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace)

List<GWTRecord>

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, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace)

List<GWTMail>

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, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace, String language)

List<GWTFolder>

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.

GWTWorkspace gwtUserWorkspace parameter is used internally to copy API objects ( Document, Folder, Record, Mail ) to GWT Objects ( GWTDocument, GWTFolder, GWTRecord, GWTMail ).

Example of code:

List<Folder> results = OKMSearch.getInstance().getFoldersByPropertyValue(null, group, property, value);

for (Folder fld : results) {
    folderList.add(GWTUtil.copy(fld, gwtUserWorkspace));
}

Map<String, GWTFilter> mapFilter? parameter is used internally for filtering. It only gets some value when filtering is enabled in UI

Example of code:

if (mapFilter != null) {
    FilterUtils.filter(gwtUserWorkspace, folderList, mapFilter);
}

Example of the Stack Metadata implementation

package com.openkm.plugin.stack.metadata;

import com.openkm.api.OKMPropertyGroup;
import com.openkm.api.OKMSearch;
import com.openkm.bean.*;
import com.openkm.bean.form.*;
import com.openkm.core.Config;
import com.openkm.dao.KeyValueDAO;
import com.openkm.dao.bean.KeyValue;
import com.openkm.frontend.client.bean.*;
import com.openkm.frontend.client.widget.filebrowser.GWTFilter;
import com.openkm.plugin.stack.StackMetadataAdapter;
import com.openkm.servlet.frontend.util.FolderComparator;
import com.openkm.util.GWTUtil;
import com.openkm.util.pagination.FilterUtils;
import net.xeoh.plugins.base.annotations.PluginImplementation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 */
@PluginImplementation
public class ParentChildStackMetadataAdapter implements StackMetadataAdapter {
	private static Logger log = LoggerFactory.getLogger(ParentChildStackMetadataAdapter.class);

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

	@Override
	public List<GWTFolder> getFolderMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace, String language) {
		List<GWTFolder> 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.getInstance().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;
									}
								}
							}
						}
					}
				}

				List<Folder> results = OKMSearch.getInstance().getFoldersByPropertyValue(null, group, property, value);
				for (Folder fld : results) {
					folderList.add(GWTUtil.copy(fld, gwtUserWorkspace));
				}
			}

			if (mapFilter != null) {
				FilterUtils.filter(gwtUserWorkspace, folderList, mapFilter);
			}

			Collections.sort(folderList, FolderComparator.getInstance(language));

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

		return folderList;
	}

	@Override
	public List<GWTDocument> getDocumentMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace) {
		List<GWTDocument> 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.getInstance().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;
									}
								}
							}
						}
					}
				}

				List<Document> results = OKMSearch.getInstance().getDocumentsByPropertyValue(null, group, property, value);

				for (Document doc : results) {
					docList.add(GWTUtil.copy(doc, gwtUserWorkspace));
				}
			}

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

		return docList;
	}

	@Override
	public List<GWTRecord> getRecordMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace) {
		List<GWTRecord> 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.getInstance().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;
									}
								}
							}
						}
					}
				}

				List<Record> results = OKMSearch.getInstance().getRecordsByPropertyValue(null, group, property, value);
				for (Record rec : results) {
					recordList.add(GWTUtil.copy(rec, gwtUserWorkspace));
				}
			}

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

		return recordList;
	}

	@Override
	public List<GWTMail> getMailMetadataChildren(String fldPath, Map<String, GWTFilter> mapFilter, GWTWorkspace gwtUserWorkspace) {
		List<GWTMail> 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.getInstance().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;
									}
								}
							}
						}
					}
				}

				List<Mail> results = OKMSearch.getInstance().getMailsByPropertyValue(null, group, property, value);

				for (Mail mail : results) {
					mailList.add(GWTUtil.copy(mail, gwtUserWorkspace));
				}
			}

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

		return mailList;
	}

	@Override
	public List<GWTFolder> getChildren(String fldPath, boolean extraColumns, Map<String, GWTFilter> mapFilter) {
		List<GWTFolder> folderList = new ArrayList<>();

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

						for (FormElement formElement : OKMPropertyGroup.getInstance().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) {
							GWTFolder gWTFolder = new GWTFolder();
							String path = fldPath + "/" + pg.getName();
							gWTFolder.initMetadata(path, pg.getLabel(),
									OKMPropertyGroup.getInstance().getPropertyGroupForm(null, pg.getName()).size() > 0);
							folderList.add(gWTFolder);
						}
					}
					break;

				case 2: // getting property level
					String grpName = fldPath.substring(fldPath.lastIndexOf("/") + 1);
					for (FormElement formElement : OKMPropertyGroup.getInstance().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()) {
									GWTFolder gWTFolder = new GWTFolder();
									String path = fldPath + "/" + formElement.getName();
									gWTFolder.initMetadata(path, formElement.getLabel(), false);
									folderList.add(gWTFolder);
								}
							} else if (formElement instanceof SuggestBox || formElement instanceof CheckBox) {
								GWTFolder gWTFolder = new GWTFolder();
								String path = fldPath + "/" + formElement.getName();
								gWTFolder.initMetadata(path, formElement.getLabel(), false);
								folderList.add(gWTFolder);
							}
						}
					}
					break;

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

					for (FormElement formElement : OKMPropertyGroup.getInstance().getPropertyGroupForm(null, grpName)) {
						if (formElement.getName().equals(propertyName)) {
							if (formElement instanceof Select) {
								for (Option option : ((Select) formElement).getOptions()) {
									GWTFolder gWTFolder = new GWTFolder();
									String path = fldPath + "/" + option.getValue();
									gWTFolder.initMetadata(path, option.getLabel(), false);
									folderList.add(gWTFolder);
								}
							} 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 : KeyValueDAO.getKeyValues(sb.getTable(), sqlFilter)) {
									GWTFolder gWTFolder = new GWTFolder();
									String path = fldPath + "/" + keyValue.getKey();
									gWTFolder.initMetadata(path, keyValue.getValue(), false);
									folderList.add(gWTFolder);
								}
							} else if (formElement instanceof CheckBox) {
								GWTFolder gWTFolder = new GWTFolder();
								String path = fldPath + "/true";
								gWTFolder.initMetadata(path, "true", false);
								folderList.add(gWTFolder);
								gWTFolder = new GWTFolder();
								path = fldPath + "/false";
								gWTFolder.initMetadata(path, "false", false);
								folderList.add(gWTFolder);
							}
							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.getInstance().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)) {
										GWTFolder gWTFolder = new GWTFolder();
										String path = fldPath + "/" + option.getValue();
										gWTFolder.initMetadata(path, option.getLabel(), false);
										folderList.add(gWTFolder);
									}
								}
							}
						}
					}
					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 GWTFolder getProperties(String fldPath) {
		GWTFolder gWTFolder = new GWTFolder();

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

			switch (fldPath.split("/").length - 1) {
				case 1:
					gWTFolder.initMetadata(fldPath, OKMPropertyGroup.getInstance().getAllGroups(null).size() > 0);
					break;

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

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

					gWTFolder.initMetadata(fldPath, label,
							OKMPropertyGroup.getInstance().getPropertyGroupForm(null, grpName).size() > 0);
					break;

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

					for (FormElement formElement : OKMPropertyGroup.getInstance().getPropertyGroupForm(null, grpName)) {
						if (formElement.getName().equals(propertyName)) {
							gWTFolder.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.getInstance().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)) {
											gWTFolder.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 : KeyValueDAO.getKeyValues(sb.getTable(), sqlFilter)) {
									if (keyValue.getKey().equals(value)) {
										gWTFolder.initMetadata(fldPath, keyValue.getValue(), false);
										break;
									}
								}
							} else if (formElement instanceof CheckBox) {
								gWTFolder.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.getInstance().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)) {
										gWTFolder.initMetadata(fldPath, option.getLabel(), false);
										break;
									}
								}
							}
						}
					}
					break;

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

		return gWTFolder;
	}
}

?

?