org.hippoecm.frontend.plugins.standardworkflow.PermissionsFolderWorkflowPlugin.java Source code

Java tutorial

Introduction

Here is the source code for org.hippoecm.frontend.plugins.standardworkflow.PermissionsFolderWorkflowPlugin.java

Source

/*
 * Copyright 2013-2015 Hippo B.V. (http://www.onehippo.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.hippoecm.frontend.plugins.standardworkflow;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.RefreshingView;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.request.resource.ResourceReference;
import org.apache.wicket.util.value.IValueMap;
import org.apache.wicket.util.value.ValueMap;
import org.hippoecm.addon.workflow.AbstractWorkflowDialog;
import org.hippoecm.addon.workflow.IWorkflowInvoker;
import org.hippoecm.addon.workflow.StdWorkflow;
import org.hippoecm.addon.workflow.WorkflowDescriptorModel;
import org.hippoecm.frontend.dialog.IDialogService;
import org.hippoecm.frontend.l10n.ResourceBundleModel;
import org.hippoecm.frontend.plugin.IPluginContext;
import org.hippoecm.frontend.plugin.config.IPluginConfig;
import org.hippoecm.frontend.plugins.standards.icon.HippoIcon;
import org.hippoecm.frontend.service.render.RenderPlugin;
import org.hippoecm.frontend.session.UserSession;
import org.hippoecm.frontend.skin.CmsIcon;
import org.hippoecm.frontend.skin.Icon;
import org.hippoecm.repository.api.HippoNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PermissionsFolderWorkflowPlugin extends RenderPlugin {

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

    private static final ResourceReference CSS = new CssResourceReference(PermissionsFolderWorkflowPlugin.class,
            "PermissionsFolderWorkflowPlugin.css");
    private static final String QUERY_LANGUAGE_QUERIES = Query.XPATH;
    private static final String QUERY_STATEMENT_QUERIES = "hippo:configuration/hippo:queries/hippo:templates//element(*, hippostd:templatequery)";
    private static final String HIPPO_TEMPLATES_BUNDLE_NAME = "hippo:templates";

    private static final List<String> EMPTY = new ArrayList<>();

    private String name;
    private String selected;
    private final List<DisplayModel> folderTypesList = new ArrayList<>();

    public PermissionsFolderWorkflowPlugin(IPluginContext context, final IPluginConfig config) {
        super(context, config);

        add(new StdWorkflow("queryModifier", new StringResourceModel("query-label", this, null), context,
                getModel()) {

            @Override
            protected Component getIcon(final String id) {
                return HippoIcon.inline(id, CmsIcon.FILE_UNLOCKED);
            }

            @Override
            protected IDialogService.Dialog createRequestDialog() {
                try {
                    Node folder = getModel().getNode();
                    PermissionsFolderWorkflowPlugin.this.name = ((HippoNode) folder).getDisplayName();
                    try {
                        Value[] values = folder.getProperty("hippostd:foldertype").getValues();
                        for (Value value : values) {
                            folderTypesList.add(new DisplayModel(value.getString()));
                        }
                    } catch (RepositoryException e) {
                        log.error("Couldn't get foldertypes from folder", e);
                    }
                } catch (RepositoryException ex) {
                    log.error("Couldn't get display name for folder", ex);
                    PermissionsFolderWorkflowPlugin.this.name = "";
                }
                Session session = UserSession.get().getJcrSession();
                Query query = null;

                try {
                    QueryManager qMgr = session.getWorkspace().getQueryManager();
                    query = qMgr.createQuery(QUERY_STATEMENT_QUERIES, QUERY_LANGUAGE_QUERIES);
                } catch (RepositoryException ex) {
                    log.error("Error retrieving all templatequeries: {}", ex);
                }

                return new PermissionsConfirmDialog(getModel(), this,
                        new PropertyModel(PermissionsFolderWorkflowPlugin.this, "name"), query);
            }

            @Override
            protected void execute(WorkflowDescriptorModel model) throws Exception {
                Session session = ((UserSession) getSession()).getJcrSession();
                Node folder = model.getNode();
                String[] store = new String[folderTypesList.size()];
                for (IModel propertyModel : folderTypesList) {
                    store = (String[]) ArrayUtils.add(store, propertyModel.getObject());
                }
                folder.setProperty("hippostd:foldertype", store);
                session.save();
            }
        });
    }

    @Override
    public WorkflowDescriptorModel getModel() {
        return (WorkflowDescriptorModel) super.getModel();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSelected() {
        return selected;
    }

    public void setSelected(String selected) {
        this.selected = selected;
    }

    public class PermissionsConfirmDialog extends AbstractWorkflowDialog {

        protected final IValueMap CUSTOM = new ValueMap("width=475,height=425").makeImmutable();
        protected static final String EXCLUDE = "exclude";

        private IModel folderName;

        @SuppressWarnings({ "unchecked", "rawtypes" })
        public PermissionsConfirmDialog(WorkflowDescriptorModel model, IWorkflowInvoker invoker, IModel folderName,
                Query query) {
            super(model, invoker);

            this.folderName = folderName;

            final IPluginConfig pluginConfig = getPluginConfig();
            List<String> excludes;
            if (pluginConfig.containsKey(EXCLUDE)) {
                excludes = Arrays.asList(pluginConfig.getStringArray(EXCLUDE));
            } else {
                excludes = EMPTY;
            }

            //list of available queries:::
            final List<String> modelList = new ArrayList<>();
            try {
                if (query != null) {
                    QueryResult result = query.execute();
                    for (NodeIterator queryIterator = result.getNodes(); queryIterator.hasNext();) {
                        Node document = queryIterator.nextNode();
                        if (document != null) {
                            final String documentName = document.getName();
                            DisplayModel displayModel = new DisplayModel(documentName);
                            if (!folderTypesList.contains(displayModel) && !excludes.contains(documentName)) {
                                modelList.add(documentName);
                            }
                        }
                    }
                } else {
                    error("Error fetching existing foldertypes");
                }
            } catch (RepositoryException ex) {
                log.error("Error fetching existing foldertypes", ex);
                error("Error fetching existing foldertypes");
            }

            Collections.sort(modelList);

            final RefreshingView<DisplayModel> view = new RefreshingView<DisplayModel>("list-item-repeater") {
                private static final long serialVersionUID = 1L;

                @Override
                protected Iterator getItemModels() {
                    return folderTypesList.iterator();
                }

                @Override
                protected void populateItem(final Item item) {
                    final DisplayModel valueModel = (DisplayModel) item.getModel();

                    item.add(new Label("list-item-category", valueModel.getDisplayObject()));

                    Fragment fragment = new Fragment("action-fragment", "action-controls",
                            PermissionsConfirmDialog.this);

                    WebMarkupContainer controls = new WebMarkupContainer("controls");
                    fragment.add(controls);

                    MarkupContainer remove = new AjaxLink("remove") {
                        private static final long serialVersionUID = 1L;

                        @Override
                        public void onClick(AjaxRequestTarget target) {
                            folderTypesList.remove(valueModel);
                            modelList.add(valueModel.getObject());
                            Collections.sort(modelList);
                            target.add(PermissionsConfirmDialog.this);
                        }
                    };
                    controls.add(remove);
                    final HippoIcon removeIcon = HippoIcon.fromSprite("remove-icon", Icon.TIMES);
                    remove.add(removeIcon);

                    MarkupContainer upLink = new AjaxLink("up") {
                        private static final long serialVersionUID = 1L;

                        @Override
                        public void onClick(AjaxRequestTarget target) {
                            final int i = folderTypesList.indexOf(valueModel);
                            Collections.swap(folderTypesList, i, i - 1);
                            target.add(PermissionsConfirmDialog.this);
                        }
                    };
                    boolean isFirst = (item.getIndex() == 0);
                    upLink.setEnabled(!isFirst);
                    controls.add(upLink);
                    final HippoIcon upIcon = HippoIcon.fromSprite("up-icon", Icon.ARROW_UP);
                    upLink.add(upIcon);

                    MarkupContainer downLink = new AjaxLink("down") {
                        private static final long serialVersionUID = 1L;

                        @Override
                        public void onClick(AjaxRequestTarget target) {
                            final int i = folderTypesList.indexOf(valueModel);
                            Collections.swap(folderTypesList, i, i + 1);
                            target.add(PermissionsConfirmDialog.this);
                        }
                    };
                    boolean isLast = (item.getIndex() == folderTypesList.size() - 1);
                    downLink.setEnabled(!isLast);
                    controls.add(downLink);
                    final HippoIcon downIcon = HippoIcon.fromSprite("down-icon", Icon.ARROW_DOWN);
                    downLink.add(downIcon);

                    item.add(fragment);

                    item.add(new AttributeAppender("class", new AbstractReadOnlyModel() {
                        private static final long serialVersionUID = 1L;

                        public Object getObject() {
                            return ((item.getIndex() & 1) == 1) ? "qfwli-even" : "qfwli-odd";
                        }
                    }, " "));
                }
            };

            add(view);

            Label addTitle = new Label("title-query-add", new StringResourceModel("title-query-add",
                    PermissionsConfirmDialog.this, null, folderName.getObject()));
            add(addTitle);

            IChoiceRenderer<String> folderTypeRenderer = new IChoiceRenderer<String>() {
                private static final long serialVersionUID = 1L;

                public String getDisplayValue(final String object) {
                    String categoryLabel = new StringResourceModel("add-category",
                            PermissionsFolderWorkflowPlugin.this, null,
                            new ResourceBundleModel(HIPPO_TEMPLATES_BUNDLE_NAME, object)).getString();
                    return String.format("%s (%s)", categoryLabel, object);//categoryLabel;
                }

                public String getIdValue(String object, int index) {
                    return object;
                }
            };

            final DropDownChoice querySelection;

            add(querySelection = new DropDownChoice("query-selection",
                    new PropertyModel(PermissionsFolderWorkflowPlugin.this, "selected"), modelList,
                    folderTypeRenderer));
            querySelection.add(new AjaxFormComponentUpdatingBehavior("onchange") {
                private static final long serialVersionUID = 1L;

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    if (StringUtils.isNotEmpty(querySelection.getInput())) {
                        folderTypesList.add(new DisplayModel(querySelection.getInput()));
                        modelList.remove(querySelection.getInput());
                        target.add(PermissionsConfirmDialog.this);
                    }
                }
            });
            querySelection.setNullValid(true);
        }

        @Override
        public void renderHead(IHeaderResponse response) {
            super.renderHead(response);
            response.render(CssHeaderItem.forReference(CSS));
        }

        @Override
        public IModel<String> getTitle() {
            return new StringResourceModel("title", this, null, folderName.getObject());
        }

        @Override
        public IValueMap getProperties() {
            return CUSTOM;
        }
    }

    private class DisplayModel extends Model<String> {
        private static final long serialVersionUID = 1L;

        public DisplayModel(String input) {
            super(input);
        }

        public String getDisplayObject() {
            String categoryLabel = new StringResourceModel("add-category", PermissionsFolderWorkflowPlugin.this,
                    null, new ResourceBundleModel(HIPPO_TEMPLATES_BUNDLE_NAME, this.getObject())).getString();
            return String.format("%s (%s)", categoryLabel, this.getObject()); //categoryLabel;//
        }

    }

}