View Javadoc
1   /**
2    * This file Copyright (c) 2019 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.form.field.definition.migration;
35  
36  import info.magnolia.ui.chooser.definition.SingleItemWorkbenchChooserDefinition;
37  import info.magnolia.ui.datasource.jcr.JcrDatasource;
38  import info.magnolia.ui.editor.converter.JcrNodeToIdentifierConverter;
39  import info.magnolia.ui.field.LinkFieldDefinition;
40  import info.magnolia.ui.form.field.converter.BaseIdentifierToPathConverter;
41  import info.magnolia.ui.form.field.converter.IdentifierToPathConverter;
42  
43  import java.util.HashMap;
44  import java.util.Map;
45  import java.util.Optional;
46  import java.util.regex.Matcher;
47  import java.util.regex.Pattern;
48  
49  import javax.jcr.Node;
50  
51  import org.apache.commons.lang3.StringUtils;
52  import org.slf4j.Logger;
53  import org.slf4j.LoggerFactory;
54  
55  import com.vaadin.data.Converter;
56  import com.vaadin.data.Result;
57  import com.vaadin.data.ValueContext;
58  
59  /**
60   * Converter from old {@link info.magnolia.ui.form.field.definition.LinkFieldDefinition} to new {@link LinkFieldDefinition}.
61   * @param <T> item type
62   */
63  public class LinkFieldDefinitionConverter<T> extends AbstractConfiguredFieldDefinitionConverter<T, LinkFieldDefinition<T>, info.magnolia.ui.form.field.definition.LinkFieldDefinition> {
64  
65      private final Logger log = LoggerFactory.getLogger(LinkFieldDefinitionConverter.class);
66  
67      private Map<String, String> APP_MAPPING = new HashMap<String, String>() {{
68          put("pages", "pages-app");
69          put("segmentation", "segmentation-app");
70          put("personas", "personas-app");
71      }};
72  
73      @Override
74      public LinkFieldDefinition<T> convert(info.magnolia.ui.form.field.definition.LinkFieldDefinition oldDefinition) {
75          LinkFieldDefinition<T> newDefinition = super.convert(oldDefinition);
76          newDefinition.setButtonSelectOtherLabel(convertButtonLabel(oldDefinition.getButtonSelectOtherLabel(), oldDefinition));
77          newDefinition.setButtonSelectNewLabel(convertButtonLabel(oldDefinition.getButtonSelectNewLabel(), oldDefinition));
78          newDefinition.setEditable(oldDefinition.isFieldEditable());
79          newDefinition.setPlaceholder(oldDefinition.getPlaceholder());
80          newDefinition.setChooser(createSingleItemWorkbenchChooser(oldDefinition));
81          if (oldDefinition.getIdentifierToPathConverter() != null) {
82              newDefinition.setConverterClass((Class<? extends Converter<T, ?>>) convertIdentifierToPathConverter(oldDefinition.getIdentifierToPathConverter()));
83          }
84          return newDefinition;
85      }
86  
87      private String convertButtonLabel(String buttonSelectLabel, info.magnolia.ui.form.field.definition.LinkFieldDefinition oldDefinition) {
88          return Optional.ofNullable(buttonSelectLabel)
89                  .map(label -> label.endsWith("buttonSelectOtherLabel") ? oldDefinition.getButtonSelectOtherDefaultLabel() : label)
90                  .map(label -> label.endsWith("buttonSelectNewLabel") ? oldDefinition.getButtonSelectNewDefaultLabel() : label)
91                  .orElse(buttonSelectLabel);
92      }
93  
94      @Override
95      LinkFieldDefinition<T> createNewDefinition(info.magnolia.ui.form.field.definition.LinkFieldDefinition oldDefinition) {
96          return new LinkFieldDefinition<>();
97      }
98  
99      @Override
100     T convertDefaultValue(info.magnolia.ui.form.field.definition.LinkFieldDefinition oldDefinition, LinkFieldDefinition<T> newDefinition) {
101         return (T) oldDefinition.getDefaultValue();
102     }
103 
104     private SingleItemWorkbenchChooserDefinition<T> createSingleItemWorkbenchChooser(info.magnolia.ui.form.field.definition.LinkFieldDefinition oldDefinition) {
105         CompatibilityAppAwareWorkbenchChooserDefinition<T> appAwareWorkbenchChooserDefinition = new CompatibilityAppAwareWorkbenchChooserDefinition<>();
106         appAwareWorkbenchChooserDefinition.setAppName(APP_MAPPING.getOrDefault(oldDefinition.getAppName(), oldDefinition.getAppName()));
107 
108         SingleItemWorkbenchChooserDefinition<T> chooserDefinition = new SingleItemWorkbenchChooserDefinition<>();
109         chooserDefinition.setWorkbenchChooser(appAwareWorkbenchChooserDefinition);
110         return chooserDefinition;
111     }
112 
113     private Class<? extends Converter<Node, ?>> convertIdentifierToPathConverter(IdentifierToPathConverter identifierToPathConverter) {
114         if (identifierToPathConverter instanceof BaseIdentifierToPathConverter) {
115             return JcrNodeToIdentifierConverter.class;
116         }
117         if ("info.magnolia.dam.app.assets.field.translator.AssetCompositeIdKeyTranslator".equals(identifierToPathConverter.getClass().getName())) {
118             return AssetCompositeIdKeyTranslator.class;
119         }
120         log.error("Can't convert {}, because there's no replacement in new ui framework", identifierToPathConverter);
121         return null;
122     }
123 
124     @Override
125     public boolean supports(info.magnolia.ui.form.field.definition.LinkFieldDefinition oldDefinition) {
126         if (oldDefinition.getIdentifierToPathConverter() == null ||
127                 convertIdentifierToPathConverter(oldDefinition.getIdentifierToPathConverter()) != null) {
128             return super.supports(oldDefinition);
129         }
130         return false;
131     }
132 
133     /**
134      * Convert an asset's composite id to a path and vice versa.
135      * @deprecated since 6.2, used as replacement for {@link info.magnolia.dam.app.assets.field.translator.AssetCompositeIdKeyTranslator} when
136      * converting old framework definition to new one
137      */
138     @Deprecated
139     public static class AssetCompositeIdKeyTranslator extends JcrNodeToIdentifierConverter {
140 
141         private final Logger log = LoggerFactory.getLogger(AssetCompositeIdKeyTranslator.class);
142 
143         private static final Pattern ASSET_ITEM_KEY_PATTERN = Pattern.compile("^(.+?):(.+)$");
144 
145         public AssetCompositeIdKeyTranslator(JcrDatasource datasource) {
146             super(datasource);
147         }
148 
149         @Override
150         public Result<String> convertToModel(Node node, ValueContext context) {
151             Result<String> result = super.convertToModel(node, context);
152             return result.flatMap(value -> {
153                 if (StringUtils.isBlank(value)) {
154                     return Result.ok(null);
155                 }
156                 return Result.ok("jcr:" + value);
157             });
158         }
159 
160         @Override
161         public Node convertToPresentation(String compositeId, ValueContext context) {
162             if (StringUtils.isBlank(compositeId)) {
163                 return null;
164             }
165             Matcher matcher = ASSET_ITEM_KEY_PATTERN.matcher(compositeId);
166             if (!matcher.matches()) {
167                 log.error("[{}] is not a valid ItemKey", compositeId);
168                 return null;
169             }
170             return super.convertToPresentation(matcher.group(2), context);
171         }
172     }
173 }