View Javadoc
1   /**
2    * This file Copyright (c) 2011-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.contentapp.field;
35  
36  import info.magnolia.event.EventBus;
37  import info.magnolia.jcr.util.SessionUtil;
38  import info.magnolia.objectfactory.Components;
39  import info.magnolia.ui.api.context.UiContext;
40  import info.magnolia.ui.api.event.ChooseDialogEventBus;
41  import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
42  import info.magnolia.ui.form.field.factory.AbstractFieldFactory;
43  import info.magnolia.ui.form.field.factory.LinkFieldFactory;
44  import info.magnolia.ui.vaadin.integration.jcr.JcrItemId;
45  import info.magnolia.ui.workbench.WorkbenchPresenter;
46  import info.magnolia.ui.workbench.WorkbenchView;
47  import info.magnolia.ui.workbench.event.SelectionChangedEvent;
48  
49  import javax.inject.Inject;
50  import javax.inject.Named;
51  import javax.jcr.Node;
52  import javax.jcr.RepositoryException;
53  
54  import org.apache.commons.lang3.StringUtils;
55  import org.slf4j.Logger;
56  import org.slf4j.LoggerFactory;
57  
58  import com.vaadin.v7.data.Item;
59  import com.vaadin.v7.ui.Field;
60  
61  /**
62   * Creates and initializes a {@link TextAndContentViewField} field based on a
63   * field definition. This field is used to create an Input text field with a
64   * large ContentView area. The column value to handle is coming from the
65   * definition. If this value is not set, or the column is not part of the row
66   * elements, the <b>Node Path is used</b>.
67   */
68  public class LinkFieldSelectionFactory extends AbstractFieldFactory<LinkFieldSelectionDefinition, String> {
69  
70      private static final Logger log = LoggerFactory.getLogger(LinkFieldSelectionFactory.class);
71  
72      private final EventBus chooseDialogEventBus;
73  
74      private final WorkbenchPresenter workbenchPresenter;
75  
76      private final String propertyName;
77  
78      private TextAndContentViewField textContent;
79  
80      @Inject
81      public LinkFieldSelectionFactory(
82              LinkFieldSelectionDefinition definition, Item relatedFieldItem, UiContext uiContext, I18NAuthoringSupport i18nAuthoringSupport,
83              WorkbenchPresenter workbenchPresenter, @Named(ChooseDialogEventBus.NAME) final EventBus chooseDialogEventBus) {
84          super(definition, relatedFieldItem, uiContext, i18nAuthoringSupport);
85          this.workbenchPresenter = workbenchPresenter;
86          this.chooseDialogEventBus = chooseDialogEventBus;
87          // Item is build by the LinkFieldFactory and has only one property.
88          // This property has the name of property we are supposed to propagate.
89          propertyName = String.valueOf(relatedFieldItem.getItemPropertyIds().iterator().next());
90          // This will allow to set the selected value to the desired property
91          // name (handle by AbstractFieldFactory.getOrCreateProperty())
92          definition.setName(propertyName);
93      }
94  
95      /**
96       * @deprecated since 5.4.7 - use {@link #LinkFieldSelectionFactory(LinkFieldSelectionDefinition, Item, UiContext, I18NAuthoringSupport, WorkbenchPresenter, EventBus)} instead.
97       */
98      @Deprecated
99      public LinkFieldSelectionFactory(LinkFieldSelectionDefinition definition, Item relatedFieldItem, WorkbenchPresenter workbenchPresenter, @Named(ChooseDialogEventBus.NAME) final EventBus chooseDialogEventBus) {
100         this(definition, relatedFieldItem, null, Components.getComponent(I18NAuthoringSupport.class), workbenchPresenter, chooseDialogEventBus);
101     }
102 
103     @Override
104     protected Field<String> createFieldComponent() {
105         textContent = new TextAndContentViewField(definition.isDisplayTextField(), definition.isDisplayTextFieldOnTop());
106 
107         // TODO 20130513 mgeljic restore choose dialogs as real dialogs with a configured workbench field or drop that field type completely.
108         WorkbenchView workbenchView = workbenchPresenter.start(null, null, null);
109         textContent.setContentView(workbenchView);
110 
111         // Set selected item.
112         restoreContentSelection();
113 
114         // On a selected Item, propagate the specified Column Value to the TextField.
115         chooseDialogEventBus.addHandler(SelectionChangedEvent.class, new SelectionChangedEvent.Handler() {
116             @Override
117             public void onSelectionChanged(SelectionChangedEvent event) {
118                 JcrItemId firstItemId = (JcrItemId) event.getFirstItemId();
119                 final Node selected = SessionUtil.getNodeByIdentifier(firstItemId.getWorkspace(), firstItemId.getUuid());
120                 if (selected != null) {
121                     try {
122                         boolean isPropertyExisting = StringUtils.isNotBlank(propertyName)
123                                 && !LinkFieldFactory.PATH_PROPERTY_NAME.equals(propertyName) && selected.hasProperty(propertyName);
124                         textContent.setValue(isPropertyExisting ? selected.getProperty(propertyName).getString() : selected.getPath());
125                     } catch (RepositoryException e) {
126                         log.error("Not able to access the configured property. Value will not be set.", e);
127                     }
128                 }
129             }
130         });
131         return textContent;
132     }
133 
134     @Override
135     protected Class<String> getDefaultFieldType() {
136         return String.class;
137     }
138 
139     /**
140      * Set the selected item <b> only </b> if the property is the Item id (node path).
141      */
142     private void restoreContentSelection() {
143         final String propertyValue = String.valueOf(item.getItemProperty(propertyName).getValue());
144         // TODO 20130513 mgeljic get fallback root path from workbench definition
145         final String path = LinkFieldFactory.PATH_PROPERTY_NAME.equals(propertyName) && StringUtils.isNotBlank(propertyValue) ? propertyValue : "/";
146         workbenchPresenter.select(path);
147     }
148 }