View Javadoc
1   /**
2    * This file Copyright (c) 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.form.fieldtype.registry;
35  
36  import static info.magnolia.config.registry.DefinitionProvider.Problem.DefaultTypes.*;
37  import static info.magnolia.config.registry.DefinitionProvider.Problem.*;
38  import static info.magnolia.util.DeprecationUtil.getDeprecationMessage;
39  
40  import info.magnolia.config.registry.DefinitionMetadata;
41  import info.magnolia.config.registry.DefinitionProvider;
42  import info.magnolia.config.registry.validator.DefinitionValidator;
43  import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
44  import info.magnolia.ui.form.field.definition.FieldDefinition;
45  import info.magnolia.ui.form.fieldtype.definition.FieldTypeDefinition;
46  
47  import java.util.ArrayList;
48  import java.util.Collection;
49  import java.util.Optional;
50  
51  import javax.inject.Inject;
52  
53  import org.apache.commons.lang3.StringUtils;
54  
55  import lombok.Getter;
56  import net.sf.cglib.proxy.Enhancer;
57  
58  /**
59   * Abstract validator for {@link FieldTypeDefinition}s.
60   *
61   * @param <T>
62   */
63  public abstract class AbstractFieldTypeDefinitionValidator<T> implements DefinitionValidator<T> {
64  
65      @Getter
66      private final FieldTypeDefinitionRegistry fieldTypeDefinitionRegistry;
67  
68      @Inject
69      public AbstractFieldTypeDefinitionValidator(FieldTypeDefinitionRegistry fieldTypeDefinitionRegistry) {
70          this.fieldTypeDefinitionRegistry = fieldTypeDefinitionRegistry;
71      }
72  
73      @Override
74      public Collection<DefinitionProvider.Problem> validate(DefinitionProvider<T> provider) {
75          final Collection<DefinitionProvider.Problem> problems = new ArrayList<>();
76          if (provider.isValid()) {
77              validateDefinition(problems, provider);
78          }
79          return problems;
80      }
81  
82      protected abstract void validateDefinition(Collection<DefinitionProvider.Problem> problems, DefinitionProvider<T> provider);
83  
84      protected void validateFieldDefinition(Collection<DefinitionProvider.Problem> problems, FieldDefinition fieldDefinition, String path, DefinitionMetadata dialogMetadata) {
85          Optional<DefinitionProvider<FieldTypeDefinition>> fieldTypeDefinitionDefinitionProvider = fieldTypeDefinitionRegistry
86                  .getAllProviders()
87                  .stream()
88                  .filter(provider -> provider.isValid() && provider.get().getDefinitionClass() != null && provider.get().getDefinitionClass().equals(Enhancer.isEnhanced(fieldDefinition.getClass()) ? fieldDefinition.getClass().getSuperclass() : fieldDefinition.getClass()))
89                  .findAny();
90          if (!fieldTypeDefinitionDefinitionProvider.isPresent()) {
91              reportMissingFieldTypeDefinition(problems, fieldDefinition, path);
92          } else {
93              validateFieldDefinition(problems, fieldTypeDefinitionDefinitionProvider.get(), path, dialogMetadata);
94          }
95      }
96  
97      protected void validateFieldDefinition(Collection<DefinitionProvider.Problem> problems, DefinitionProvider<FieldTypeDefinition> fieldTypeDefinitionDefinitionProvider, String path, DefinitionMetadata dialogMetadata) {
98          if (!dialogMetadata.getDeprecation().isPresent() && Optional.ofNullable(fieldTypeDefinitionDefinitionProvider.getMetadata()).flatMap(DefinitionMetadata::getDeprecation).isPresent()) {
99              DefinitionMetadata fieldTypeMetadata = fieldTypeDefinitionDefinitionProvider.getMetadata();
100             fieldTypeMetadata.getDeprecation().ifPresent(deprecation -> {
101                 String deprecationMessage = getDeprecationMessage(fieldTypeDefinitionRegistry.type().getName(), fieldTypeMetadata.getName(), deprecation.since(), deprecation.description());
102 
103                 problems.add(deprecated()
104                         .withTitle("Deprecated definition usage")
105                         .withDetails(deprecationMessage)
106                         .withLocation(path)
107                         .withType(RESOLUTION)
108                         .build());
109             });
110         }
111     }
112 
113     protected void reportMissingFieldTypeDefinition(Collection<DefinitionProvider.Problem> problems, FieldDefinition fieldDefinition, String path) {
114         problems.add(major()
115                 .withTitle("No field type definition found")
116                 .withDetails(getDetails(fieldDefinition))
117                 .withLocation(path)
118                 .withType(REFERENCES)
119                 .build());
120     }
121 
122     private String getDetails(FieldDefinition fieldDefinition) {
123         if (fieldDefinition instanceof ConfiguredFieldDefinition) {
124             ConfiguredFieldDefinitionm/field/definition/ConfiguredFieldDefinition.html#ConfiguredFieldDefinition">ConfiguredFieldDefinition configuredFieldDefinition = (ConfiguredFieldDefinition) fieldDefinition;
125             if (StringUtils.isNotBlank(configuredFieldDefinition.getFieldType())) {
126                 return "Could not find fieldType for name " + configuredFieldDefinition.getFieldType();
127             }
128         }
129         return "Could not find fieldType for definition " + fieldDefinition.getClass().getName();
130     }
131 }