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