Project

General

Profile

Download (8.58 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2018 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.event;
10

    
11
import java.beans.PropertyDescriptor;
12
import java.lang.reflect.InvocationTargetException;
13
import java.lang.reflect.Method;
14
import java.util.Collection;
15
import java.util.HashMap;
16
import java.util.Map;
17
import java.util.Stack;
18

    
19
import org.apache.commons.beanutils.BeanUtilsBean;
20
import org.apache.commons.lang3.StringUtils;
21
import org.apache.log4j.Logger;
22

    
23
import com.vaadin.ui.Component;
24

    
25
import eu.etaxonomy.cdm.model.common.CdmBase;
26
import eu.etaxonomy.cdm.ref.TypedEntityReference;
27
import eu.etaxonomy.cdm.vaadin.event.EditorActionContextFormat.TargetInfoType;
28
import eu.etaxonomy.cdm.vaadin.model.CdmEntityAdapterDTO;
29
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
30
import eu.etaxonomy.vaadin.util.PropertyIdPath;
31

    
32
/**
33
 * @author a.kohlbecker
34
 * @since Oct 29, 2018
35
 *
36
 */
37
public class EditorActionContextFormatter {
38

    
39
    public static final Logger logger = Logger.getLogger(EditorActionContextFormatter.class);
40

    
41
    private static final String NEW = "New";
42

    
43
    private static final String EDIT = "Edit";
44

    
45
    public String format(EditorActionContext cntxt, EditorActionContextFormat format) {
46

    
47
        String className = null;
48
        String targetInfo = null;
49
        String targetEntityStr = null;
50
        String createOrNew = null;
51

    
52
        Object parentEntity = cntxt.getParentEntity();
53

    
54
        if (parentEntity != null) {
55
            if (parentEntity instanceof TypedEntityReference) {
56
                className = ((TypedEntityReference) cntxt.getParentEntity()).getType().getSimpleName();
57
                createOrNew = EDIT;
58
            } else if (CdmEntityAdapterDTO.class.isAssignableFrom(parentEntity.getClass())) {
59
                CdmBase cdmEntity = ((CdmEntityAdapterDTO) parentEntity).cdmEntity();
60
                className = cdmEntity.getClass().getSimpleName();
61
                createOrNew = cdmEntity.isPersited() ? EDIT : NEW;
62
            } else if (CdmBase.class.isAssignableFrom(parentEntity.getClass())) {
63
                CdmBase cdmEntity = ((CdmBase) parentEntity);
64
                className = cdmEntity.getClass().getSimpleName();
65
                createOrNew = cdmEntity.isPersited() ? EDIT : NEW;
66
            } else {
67
                className = parentEntity.getClass().getSimpleName();
68
                className = className.replace("DTO", "");
69
                createOrNew = beanHasNonEmptyFields(parentEntity) ? EDIT : NEW;
70
            }
71
        } else {
72
            className += "[NULL_CLASS]";
73
        }
74

    
75
        if ((format.doTargetInfo || format.doTargetEntity) && cntxt.getParentView() != null && AbstractPopupEditor.class.isAssignableFrom(cntxt.getParentView().getClass())) {
76
            // the top element is the cntxt istself!! we need to dig one step deeper to get the previous popup editor
77
            // TODO chaining the EditorActionContext would ease find the contexts of parent editors
78
            Stack<EditorActionContext> ctxtStack = ((AbstractPopupEditor)cntxt.getParentView()).getEditorActionContext();
79
            int parentPopupPos = ctxtStack.size() - 2;
80
            if(parentPopupPos > -1){
81
                EditorActionContext parentCtx = ctxtStack.get(parentPopupPos);
82
                if(format.targetInfoType.equals(TargetInfoType.PROPERTIES)){
83
                    PropertyIdPath propertyIdPath = parentCtx.getTargetPropertyIdPath();
84
                    if (propertyIdPath != null) {
85
                        targetInfo = propertyIdPath.toString();
86
                    }
87
                } else {
88
                    // TargetInfoType.FIELD_CAPTION
89
                    if(parentCtx.getTargetField() != null){
90
                        Component captionComponent = parentCtx.getTargetField();
91
                        while(captionComponent != null){
92
                            targetInfo = captionComponent.getCaption();
93
                            if(targetInfo != null){
94
                                break;
95
                            }
96
                            captionComponent = captionComponent.getParent();
97
                        }
98
                    }
99
                }
100
            }
101
        }
102
        if(format.doTargetEntity){
103
            targetEntityStr = formatTargetEntityString(cntxt.parentEntity, format);
104
        }
105

    
106
        // create output
107
        String outStr = "";
108

    
109
        if (format.doCreateOrNew && createOrNew != null) {
110
            if(format.tagName != null){
111
                outStr += "<" + format.tagName + " class=\"operation " + format.classAttributes + "\">" + createOrNew + "</" + format.tagName + ">";
112
            } else {
113
                outStr += createOrNew;
114
            }
115
        }
116

    
117
        if (format.doTargetInfo) {
118
            if(targetInfo == null && format.classNameForMissingTargetData && className != null){
119
                targetInfo = className;
120
            }
121
            if(targetInfo != null){
122
                targetInfo = normalizeTargetInfo(targetInfo);
123
                if(!outStr.isEmpty()){
124
                    outStr += " ";
125
                }
126
                if(format.tagName != null){
127
                    outStr += "<" + format.tagName + " class=\"target " + format.classAttributes + "\">" + targetInfo + "</" + format.tagName + ">";
128
                } else {
129
                    outStr += targetInfo;
130
                }
131
            }
132
        }
133
        if(format.doTargetEntity && targetEntityStr != null){
134
            if(format.tagName != null){
135
                outStr += "<" + format.tagName + " class=\"target-entity" + format.classAttributes + "\">" + targetEntityStr + "</" + format.tagName + ">";
136
            } else {
137
                outStr += " (" + targetEntityStr + ")";
138
            }
139
        }
140
        return outStr;
141
    }
142

    
143
    /**
144
     * @param parentEntity
145
     * @return
146
     */
147
    private boolean beanHasNonEmptyFields(Object parentEntity) {
148
        BeanUtilsBean beanUtils = BeanUtilsBean.getInstance();
149
        Map<String, Object> description = new HashMap<>();
150
        PropertyDescriptor[] descriptors =
151
                beanUtils.getPropertyUtils().getPropertyDescriptors(parentEntity);
152
        Class<?> clazz = parentEntity.getClass();
153
        for (int i = 0; i < descriptors.length; i++) {
154

    
155
                String name = descriptors[i].getName();
156
                Method getter = beanUtils.getPropertyUtils().getReadMethod(descriptors[i]);
157
                if (getter != null) {
158
                    try {
159
                        Object value;
160
                        value = getter.invoke(parentEntity);
161
                        if(value != null){
162
                            if(Collection.class.isAssignableFrom(value.getClass())){
163
                                return !((Collection)value).isEmpty();
164
                            }
165
                            if(value instanceof String){
166
                                return !((String)value).isEmpty();
167
                            }
168
                            return true;
169
                        }
170
                    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
171
                        /* IGNORE */
172
                    }
173
                }
174

    
175
        }
176

    
177
        return false;
178
    }
179

    
180
    public String format(Collection<EditorActionContext> cntxts, EditorActionContextFormat format) {
181
        String outStr = "";
182
        for(EditorActionContext ctx : cntxts){
183
            if(!outStr.isEmpty()){
184
                outStr += " > "; // FIXME allow configuring the separator
185
            }
186
            outStr += format(ctx, format) ;
187
        }
188
        return outStr;
189
    }
190

    
191
    /**
192
     * @param value
193
     * @param format
194
     * @return
195
     */
196
    private String formatTargetEntityString(Object value, EditorActionContextFormat format) {
197

    
198
        if(value == null){
199
            return "NULL";
200
        }
201
        String outStr;
202
        if(value instanceof CdmBase){
203
            outStr = ((CdmBase)value).instanceToString();
204
        } else if(value instanceof CdmEntityAdapterDTO) {
205
            outStr = value.getClass().getSimpleName() + ": ";
206
            outStr += ((CdmEntityAdapterDTO)value).cdmEntity().toString();
207
        } else {
208
            outStr = value.getClass().getSimpleName() + ": " + value.toString();
209
        }
210
        return outStr;
211
    }
212

    
213
    /**
214
     * @param targetInfo
215
     * @return
216
     */
217
    public String normalizeTargetInfo(String targetInfo) {
218
        targetInfo = StringUtils.join(StringUtils.splitByCharacterTypeCamelCase(targetInfo), " ");
219
        targetInfo = targetInfo.toLowerCase();
220
        return targetInfo;
221
    }
222

    
223
}
(10-10/29)