001/*
002 *  Copyright 2018 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.runtime.model;
017
018import java.util.Map;
019import java.util.Objects;
020
021import org.apache.cocoon.ProcessingException;
022import org.apache.commons.lang3.StringUtils;
023
024import org.ametys.core.util.SizeUtils.ExcludeFromSizeCalculation;
025import org.ametys.plugins.core.ui.help.HelpLink;
026import org.ametys.runtime.i18n.I18nizableText;
027
028/**
029 * View reference to an element definition
030 */
031public class ViewElement implements ModelViewItem<ElementDefinition>
032{
033    @ExcludeFromSizeCalculation
034    private ElementDefinition _definition;
035    
036    private I18nizableText _label;
037    private I18nizableText _description;
038    
039    public ElementDefinition getDefinition()
040    {
041        return _definition;
042    }
043
044    public void setDefinition(ElementDefinition definition)
045    {
046        if (definition == null)
047        {
048            throw new IllegalArgumentException("Try to set a null definition to the view element");
049        }
050        _definition = definition;
051    }
052    
053    public String getName()
054    {
055        if (_definition != null)
056        {
057            return _definition.getName();
058        }
059        else
060        {
061            return null;
062        }
063    }
064    
065    public void setLabel(I18nizableText label)
066    {
067        _label = label;
068    }
069    
070    public void setDescription(I18nizableText description)
071    {
072        _description = description;
073    }
074
075    @Override
076    public I18nizableText getLabel()
077    {
078        return _label != null ? _label : getDefinition().getLabel();
079    }
080    
081    @Override
082    public I18nizableText getDescription()
083    {
084        return _description != null ? _description : getDefinition().getDescription();
085    }
086    
087    public Map<String, Object> toJSON(DefinitionContext context) throws ProcessingException
088    {
089        ElementDefinition definition = getDefinition();
090        if (definition != null)
091        {
092            Map<String, Object> result = definition.toJSON(context);
093            if (!result.isEmpty())
094            {
095                // use overridden label and description if present  
096                result.put("label", getLabel());
097                result.put("description", getDescription());
098    
099                Model model = definition.getModel();
100                if (model != null)
101                {
102                    String modelId = model.getId();
103                    String family = model.getFamilyId();
104                    
105                    String path = definition.getPath();
106                    //If there is a path, and it does not starts with '/', we add one at the beginning
107                    if (StringUtils.isNotBlank(path))
108                    {
109                        path = StringUtils.prependIfMissing(path, ModelItem.ITEM_PATH_SEPARATOR);
110                    }
111                    String featureId = StringUtils.join(modelId, path);
112                    //Remove the starting '/' if present
113                    featureId = StringUtils.removeStart(featureId, ModelItem.ITEM_PATH_SEPARATOR);
114        
115                    HelpLink help = new HelpLink(family, featureId, null);
116                    result.put("help", help);
117                }
118                
119                return result;
120            }
121        }
122        
123        return Map.of();
124    }
125    
126    public void copyTo(ViewItem item)
127    {
128        assert item instanceof ViewElement;
129        ((ViewElement) item).setDefinition(getDefinition());
130    }
131    
132    public ViewElement createInstance()
133    {
134        return new ViewElement();
135    }
136
137    @Override
138    public int hashCode()
139    {
140        return Objects.hash(_definition);
141    }
142
143    @Override
144    public boolean equals(Object obj)
145    {
146        if (this == obj)
147        {
148            return true;
149        }
150        if (obj == null)
151        {
152            return false;
153        }
154        if (getClass() != obj.getClass())
155        {
156            return false;
157        }
158        ViewElement other = (ViewElement) obj;
159        return Objects.equals(_definition, other._definition);
160    }
161
162    @Override
163    public boolean equals(Object obj, boolean checkDetails)
164    {
165        if (!equals(obj))
166        {
167            return false;
168        }
169        else if (checkDetails)
170        {
171            ViewElement other = (ViewElement) obj;
172            return Objects.equals(_label, other._label) && Objects.equals(_description, other._description);
173        }
174        else
175        {
176            return true;
177        }
178    }
179}