View Javadoc
1   /**
2    * Copyright 2014-2024 Bloomreach B.V. (<a href="http://www.bloomreach.com">http://www.bloomreach.com</a>)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.onehippo.forge.exdocpicker.impl.folder;
17  
18  import java.io.Serializable;
19  
20  import javax.jcr.RepositoryException;
21  
22  import org.apache.commons.lang3.StringUtils;
23  import org.apache.wicket.model.IModel;
24  import org.apache.wicket.model.Model;
25  import org.apache.wicket.model.StringResourceModel;
26  import org.apache.wicket.request.resource.PackageResourceReference;
27  import org.apache.wicket.request.resource.ResourceReference;
28  import org.hippoecm.addon.workflow.StdWorkflow;
29  import org.hippoecm.addon.workflow.WorkflowDescriptorModel;
30  import org.hippoecm.frontend.dialog.AbstractDialog;
31  import org.hippoecm.frontend.dialog.IDialogFactory;
32  import org.hippoecm.frontend.dialog.IDialogService;
33  import org.hippoecm.frontend.model.JcrNodeModel;
34  import org.hippoecm.frontend.plugin.IPluginContext;
35  import org.hippoecm.frontend.plugin.config.IPluginConfig;
36  import org.hippoecm.frontend.service.render.RenderPlugin;
37  import org.hippoecm.repository.api.WorkflowDescriptor;
38  import org.hippoecm.repository.standardworkflow.FolderWorkflow;
39  import org.onehippo.forge.exdocpicker.api.ExternalDocumentCollection;
40  import org.onehippo.forge.exdocpicker.api.ExternalDocumentServiceContext;
41  import org.onehippo.forge.exdocpicker.api.ExternalDocumentServiceFacade;
42  import org.onehippo.forge.exdocpicker.api.PluginConstants;
43  import org.onehippo.forge.exdocpicker.impl.SimpleExternalDocumentServiceContext;
44  import org.onehippo.forge.exdocpicker.impl.field.TextSearchExternalDocumentFieldBrowserDialog;
45  import org.slf4j.Logger;
46  import org.slf4j.LoggerFactory;
47  
48  public class ExternalDocumentFolderActionWorkflowMenuItemPlugin extends RenderPlugin<WorkflowDescriptor> {
49  
50      private static final long serialVersionUID = 1L;
51  
52      private static final Logger log = LoggerFactory.getLogger(ExternalDocumentFolderActionWorkflowMenuItemPlugin.class);
53  
54      private final WorkflowDescriptorModel folderWorkflowModel;
55  
56      private ExternalDocumentServiceFacade<Serializable> exdocService;
57      private ExternalDocumentCollection<Serializable> curDocCollection;
58      private ExternalDocumentServiceContext extDocServiceContext;
59  
60      @SuppressWarnings("unchecked")
61      public ExternalDocumentFolderActionWorkflowMenuItemPlugin(IPluginContext context, IPluginConfig config) {
62          super(context, config);
63  
64          folderWorkflowModel = (WorkflowDescriptorModel) getModel();
65  
66          JcrNodeModel folderNodeModel;
67          try {
68              folderNodeModel = new JcrNodeModel(folderWorkflowModel.getNode());
69          } catch (RepositoryException e) {
70              throw new IllegalStateException("Folder node is not resolvable.", e);
71          }
72  
73          setExternalDocumentServiceFacade((ExternalDocumentServiceFacade<Serializable>) createExternalDocumentService());
74          setExternalDocumentServiceContext(
75                  new SimpleExternalDocumentServiceContext(this, config, context, folderNodeModel));
76  
77          add(new StdWorkflow<FolderWorkflow>("menuItem", getMenuItemLabelModel(), folderWorkflowModel) {
78  
79              private static final long serialVersionUID = 1L;
80  
81              @Override
82              protected ResourceReference getIcon() {
83                  return getMenuItemIconResourceReference();
84              }
85  
86              @Override
87              protected String execute(FolderWorkflow workflow) throws Exception {
88                  final IDialogService dialogService = getDialogService();
89  
90                  if (!dialogService.isShowingDialog()) {
91                      final IDialogFactory dialogFactory = createDialogFactory();
92                      dialogService.show(dialogFactory.createDialog());
93                  }
94  
95                  return null;
96              }
97          });
98      }
99  
100     protected IModel<String> getMenuItemLabelModel() {
101         String menuItemLabel = getPluginConfig().getString("exdocfield.menu.label", PluginConstants.DEFAULT_FIELD_CAPTION);
102         return new StringResourceModel(menuItemLabel, this, null).setDefaultValue(menuItemLabel);
103     }
104 
105     protected ResourceReference getMenuItemIconResourceReference() {
106         String menuItemIcon = getPluginConfig().getString("exdocfield.menu.icon");
107 
108         if (StringUtils.isBlank(menuItemIcon)) {
109             return null;
110         } else {
111             return new PackageResourceReference(ExternalDocumentFolderActionWorkflowMenuItemPlugin.class, menuItemIcon);
112         }
113     }
114 
115     protected IModel<String> getDialogTitleModel() {
116         String dialogTitle = getPluginConfig().getString("exdocfield.dialog.title");
117 
118         if (StringUtils.isBlank(dialogTitle)) {
119             return getMenuItemLabelModel();
120         } else {
121             return new StringResourceModel(dialogTitle, this, null).setDefaultValue(dialogTitle);
122         }
123     }
124 
125     /**
126      * Creates a dialog factory to create a picker dialog.
127      * @return a dialog factory to create a picker dialog
128      */
129     protected IDialogFactory createDialogFactory() {
130         return new IDialogFactory() {
131             private static final long serialVersionUID = 1L;
132 
133             public AbstractDialog<ExternalDocumentCollection<Serializable>> createDialog() {
134                 return createDialogInstance();
135             }
136         };
137     }
138 
139     /**
140      * Creates a picker dialog with which user can select external documents.
141      * @return a picker dialog with which user can select external documents
142      */
143     protected AbstractDialog<ExternalDocumentCollection<Serializable>> createDialogInstance() {
144         return new TextSearchExternalDocumentFieldBrowserDialog(getDialogTitleModel(), getExternalDocumentServiceContext(),
145                 getExternalDocumentServiceFacade(),
146                 new Model<>(getCurrentExternalDocumentCollection()));
147     }
148 
149     /**
150      * Creates a new {@link ExternalDocumentServiceFacade} instance.
151      * By default, this method reads the plugin configuration by the name, {@link PluginConstants#PARAM_EXTERNAL_DOCUMENT_SERVICE_FACADE},
152      * and instantiated an object by the FQCN configuration parameter.
153      * @return a new {@link ExternalDocumentServiceFacade} instance
154      */
155     @SuppressWarnings({ "rawtypes", "unchecked" })
156     protected ExternalDocumentServiceFacade<? extends Serializable> createExternalDocumentService() {
157         ExternalDocumentServiceFacade<? extends Serializable> service = null;
158         String serviceFacadeClassName = null;
159 
160         try {
161             serviceFacadeClassName = getPluginConfig()
162                     .getString(PluginConstants.PARAM_EXTERNAL_DOCUMENT_SERVICE_FACADE);
163             Class<? extends ExternalDocumentServiceFacade> serviceClass = (Class<? extends ExternalDocumentServiceFacade>) Class
164                     .forName(serviceFacadeClassName);
165             service = serviceClass.getDeclaredConstructor().newInstance();
166         } catch (Exception e) {
167             log.error("Failed to create external document service facade from class name, '{}'.",
168                     serviceFacadeClassName, e);
169         }
170 
171         return service;
172     }
173 
174     /**
175      * Returns the {@link ExternalDocumentServiceFacade} instance used by this plugin instance.
176      * @return the {@link ExternalDocumentServiceFacade} instance used by this plugin instance
177      */
178     protected ExternalDocumentServiceFacade<Serializable> getExternalDocumentServiceFacade() {
179         return exdocService;
180     }
181 
182     /**
183      * Sets the {@link ExternalDocumentServiceFacade} instance used by this plugin instance.
184      * @param exdocService the {@link ExternalDocumentServiceFacade} instance used by this plugin instance
185      */
186     protected void setExternalDocumentServiceFacade(ExternalDocumentServiceFacade<Serializable> exdocService) {
187         this.exdocService = exdocService;
188     }
189 
190     /**
191      * Returns the collection of the currently-selected external documents in the document.
192      * @return the collection of the currently-selected external documents in the document
193      */
194     protected ExternalDocumentCollection<Serializable> getCurrentExternalDocumentCollection() {
195         if (curDocCollection == null) {
196             curDocCollection = getExternalDocumentServiceFacade()
197                     .getFieldExternalDocuments(getExternalDocumentServiceContext());
198         }
199 
200         return curDocCollection;
201     }
202 
203     /**
204      * Sets the collection of the currently-selected external documents in the document.
205      * @param curDocCollection the collection of the currently-selected external documents in the document
206      */
207     protected void setCurrentExternalDocumentCollection(ExternalDocumentCollection<Serializable> curDocCollection) {
208         this.curDocCollection = curDocCollection;
209     }
210 
211     /**
212      * Returns the {@link ExternalDocumentServiceContext} instance.
213      * @return the {@link ExternalDocumentServiceContext} instance
214      */
215     protected ExternalDocumentServiceContext getExternalDocumentServiceContext() {
216         return extDocServiceContext;
217     }
218 
219     /**
220      * Sets the {@link ExternalDocumentServiceContext} instance.
221      * @param extDocServiceContext the {@link ExternalDocumentServiceContext} instance
222      */
223     protected void setExternalDocumentServiceContext(ExternalDocumentServiceContext extDocServiceContext) {
224         this.extDocServiceContext = extDocServiceContext;
225     }
226 }