Project

General

Profile

Download (12.6 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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.component.registration;
10

    
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.Collections;
14
import java.util.EnumSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.UUID;
18

    
19
import org.apache.log4j.Logger;
20

    
21
import com.vaadin.server.ExternalResource;
22
import com.vaadin.server.FontAwesome;
23
import com.vaadin.shared.ui.label.ContentMode;
24
import com.vaadin.ui.Button;
25
import com.vaadin.ui.Label;
26
import com.vaadin.ui.Link;
27
import com.vaadin.ui.themes.ValoTheme;
28

    
29
import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
30
import eu.etaxonomy.cdm.api.service.name.TypeDesignationDTO;
31
import eu.etaxonomy.cdm.api.service.name.TypeDesignationSet;
32
import eu.etaxonomy.cdm.api.service.name.TypeDesignationSet.TypeDesignationSetType;
33
import eu.etaxonomy.cdm.api.util.UserHelper;
34
import eu.etaxonomy.cdm.model.ICdmEntityUuidCacher;
35
import eu.etaxonomy.cdm.model.common.VersionableEntity;
36
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
37
import eu.etaxonomy.cdm.model.name.TaxonName;
38
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
39
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
40
import eu.etaxonomy.cdm.model.permission.CRUD;
41
import eu.etaxonomy.cdm.ref.TypedEntityReference;
42
import eu.etaxonomy.cdm.service.UserHelperAccess;
43
import eu.etaxonomy.cdm.strategy.cache.TagEnum;
44
import eu.etaxonomy.cdm.strategy.cache.TaggedCacheHelper;
45
import eu.etaxonomy.cdm.vaadin.component.ButtonFactory;
46
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationTermLists.RegistrationTypeDesignationStatusComparator;
47
import eu.etaxonomy.cdm.vaadin.permission.PermissionDebugUtils;
48
import eu.etaxonomy.vaadin.component.CompositeStyledComponent;
49

    
50
/**
51
 * @author a.kohlbecker
52
 * @since May 19, 2017
53
 */
54
public class RegistrationItemNameAndTypeButtons extends CompositeStyledComponent {
55

    
56
    private final static Logger logger = Logger.getLogger(RegistrationItemNameAndTypeButtons.class);
57

    
58

    
59
    private static final String DEFAULT_BUTTON_STYLES = "";
60

    
61
    private static final long serialVersionUID = -5059163772392864050L;
62

    
63
    public static final String STYLE_NAMES = "edit-button-group  " + ValoTheme.LAYOUT_COMPONENT_GROUP;
64

    
65
    private IdButton<TaxonName> nameIdButton = null;
66

    
67
    private List<TypeDesignationSetButton> typeDesignationButtons = new ArrayList<>();
68

    
69
    private List<Label> labels = new ArrayList<>();
70

    
71
    private List<ButtonWithUserEditPermission> editButtons = new ArrayList<>();
72

    
73
    private Button addTypeDesignationButton;
74

    
75
    private Label nameLabel = null;
76

    
77
    private Link identifierLink;
78

    
79
    private boolean isRegistrationLocked;
80

    
81
    private boolean isLockOverride;
82

    
83
    public RegistrationItemNameAndTypeButtons(RegistrationDTO regDto, ICdmEntityUuidCacher entitiyCacher) {
84

    
85
        isRegistrationLocked = EnumSet.of(
86
                RegistrationStatus.PUBLISHED, RegistrationStatus.REJECTED)
87
                .contains(regDto.getStatus());
88

    
89
        setWidth(100, Unit.PERCENTAGE);
90

    
91
        UserHelper userHelper;
92
        if(entitiyCacher != null){
93
            userHelper = UserHelperAccess.userHelper().withCache(entitiyCacher);
94
        } else {
95
            userHelper = UserHelperAccess.userHelper();
96
        }
97

    
98
        if(regDto.getNameRef() != null){
99
            Button nameButton = new Button("Name:");
100
            nameButton.setDescription("Edit the Name");
101
            nameIdButton = new IdButton<TaxonName>(TaxonName.class, regDto.getNameRef().getUuid(), nameButton);
102
            Label nameLabel = new Label(regDto.getNameRef().getLabel());
103
            nameLabel.setWidthUndefined();
104
            boolean userHasPermission = userHelper.userHasPermission(regDto.registration().getName(), CRUD.UPDATE);
105
            editButtons.add(new ButtonWithUserEditPermission(nameButton, userHasPermission));
106

    
107
            addComponent(nameIdButton.getButton());
108
            PermissionDebugUtils.addGainPerEntityPermissionButton(this, TaxonName.class, regDto.getNameRef().getUuid(),
109
                    EnumSet.of(CRUD.UPDATE, CRUD.DELETE), null);
110
            addComponent(nameLabel);
111
        } else {
112
            // no name in the registration! we only show the typified name as label
113
            if(regDto.getTypifiedNameRef() != null){
114
                nameLabel = new Label(regDto.getTypifiedNameRef().getLabel());
115
                addComponent(nameLabel);
116
            }
117
        }
118
        boolean userHasAddPermission = !regDto.isPersisted() || userHelper.userHasPermission(regDto.registration(), CRUD.UPDATE);
119
        Map<TypedEntityReference<? extends VersionableEntity>,TypeDesignationSet> typeDesignationSets = regDto.getOrderedTypeDesignationSets();
120

    
121
        if(typeDesignationSets != null){
122
            // order the typeDesignationSet keys so that holotypes come first, etc
123
            List<TypedEntityRefWithStatus> baseRefsByHighestStatus = new ArrayList<>();
124
            for(TypedEntityReference<? extends VersionableEntity> baseEntityRef : typeDesignationSets.keySet()) {
125
                baseRefsByHighestStatus.add(new TypedEntityRefWithStatus(baseEntityRef, typeDesignationSets.get(baseEntityRef).highestTypeStatus(new RegistrationTypeDesignationStatusComparator())));
126
            }
127

    
128
            Collections.sort(baseRefsByHighestStatus);
129

    
130
            for(TypedEntityRefWithStatus typedEntityRefWithStatus : baseRefsByHighestStatus) {
131
                TypedEntityReference<? extends VersionableEntity> baseEntity = typedEntityRefWithStatus.typedEntity;
132
                TypeDesignationSet typeDesignationSet = typeDesignationSets.get(baseEntity);
133
                if (logger.isDebugEnabled()) {logger.debug("WorkingSet:" + typeDesignationSet.getWorkingsetType() + ">" + typeDesignationSet.getBaseEntity().toString());}
134
                String buttonLabel = SpecimenOrObservationBase.class.isAssignableFrom(baseEntity.getType()) ? "Type": "NameType";
135
                Button tdButton = new Button(buttonLabel + ":");
136
                tdButton.setDescription("Edit the type designation working set");
137
                boolean userHasUpdatePermission = userHelper.userHasPermission(baseEntity.getType(), baseEntity.getUuid(), CRUD.UPDATE, CRUD.DELETE);
138
                editButtons.add(new ButtonWithUserEditPermission(tdButton, userHasUpdatePermission));
139
                addComponent(tdButton);
140

    
141
                PermissionDebugUtils.addGainPerEntityPermissionButton(this, SpecimenOrObservationBase.class,
142
                        baseEntity.getUuid(), EnumSet.of(CRUD.UPDATE, CRUD.DELETE), RegistrationStatus.PREPARATION.name());
143

    
144
                typeDesignationButtons.add(new TypeDesignationSetButton(
145
                        typeDesignationSet.getWorkingsetType(),
146
                        typeDesignationSet.getBaseEntity(),
147
                        tdButton)
148
                        );
149

    
150
                String labelText = "<span class=\"field-unit-label\">" + baseEntity.getLabel() + "</span>"; // renders the FieldUnit label
151
                for(TypeDesignationStatusBase<?> typeStatus : typeDesignationSet.keySet()){
152
                    Collection<TypeDesignationDTO> tdPerStatus = typeDesignationSet.get(typeStatus);
153
                    labelText += " <strong>" + typeStatus.getLabel() +  (tdPerStatus.size() > 1 ? "s":"" ) + "</strong>: ";
154
                    boolean isFirst = true;
155
                    for(TypeDesignationDTO<?> dtDTO : tdPerStatus) {
156
                        labelText += ( isFirst ? "" : ", ") + TaggedCacheHelper.createString(
157
                                TaggedCacheHelper.cropAt(dtDTO.getTaggedText(), TagEnum.separator, "designated\\s+[bB]y"));
158
                        isFirst = false;
159
                    }
160
                }
161

    
162
                Label label = new Label(labelText, ContentMode.HTML);
163
                label.setWidthUndefined();
164
                addComponent(label);
165
                labels.add(label);
166
            }
167
        }
168
        addTypeDesignationButton = ButtonFactory.ADD_ITEM.createButton();
169
        addTypeDesignationButton.setDescription("Add a new type designation workingset.");
170
        addTypeDesignationButton.setVisible(!isRegistrationLocked && userHasAddPermission);
171
        addComponent(addTypeDesignationButton);
172

    
173
        //TODO make responsive and use specificIdentifier in case the space gets too narrow
174
        if(regDto.isPersisted()){
175
            identifierLink = new Link(regDto.getIdentifier(), new ExternalResource(regDto.getIdentifier()));
176
            identifierLink.setEnabled(regDto.getStatus() == RegistrationStatus.PUBLISHED);
177
            addComponents(identifierLink);
178
        }
179

    
180
        iterator().forEachRemaining(c -> addStyledComponent(c));
181
        updateEditorButtonReadonlyStates();
182
        addDefaultStyles();
183
    }
184

    
185
    private void updateEditorButtonReadonlyStates() {
186
        for(ButtonWithUserEditPermission b : editButtons){
187
            boolean impossibleToUnlock = !b.userCanEdit && isLockOverride && isRegistrationLocked;
188
            b.button.setReadOnly((isRegistrationLocked && !isLockOverride) || !b.userCanEdit);
189
            b.button.setEnabled(!impossibleToUnlock);
190
            b.button.setDescription(impossibleToUnlock ? "Unlock failed due to missing permissions!" : "");
191
            b.button.setIcon(isLockOverride ? FontAwesome.UNLOCK_ALT : null);
192
        }
193
    }
194

    
195
    public IdButton<TaxonName> getNameButton() {
196
        return nameIdButton;
197
    }
198

    
199
    public List<TypeDesignationSetButton> getTypeDesignationButtons() {
200
        return typeDesignationButtons;
201
    }
202

    
203
    public Button getAddTypeDesignationButton() {
204
        return addTypeDesignationButton;
205
    }
206

    
207
    @Override
208
    protected void addDefaultStyles() {
209
        addStyleName(STYLE_NAMES);
210
        if(nameIdButton != null){
211
            nameIdButton.getButton().addStyleName(DEFAULT_BUTTON_STYLES);
212
        }
213
        if(nameLabel != null){
214
            nameLabel.addStyleName("v-disabled");
215
        }
216
        typeDesignationButtons.forEach(idb -> idb.getButton().addStyleName(DEFAULT_BUTTON_STYLES));
217
        addTypeDesignationButton.addStyleName(DEFAULT_BUTTON_STYLES);
218
    }
219

    
220
    public class TypeDesignationSetButton {
221

    
222
        private VersionableEntity baseEntity;
223
        private TypeDesignationSetType type;
224
        private Button button;
225

    
226
        public TypeDesignationSetButton(TypeDesignationSetType type, VersionableEntity baseEntity, Button button){
227
            this.type = type;
228
            this.baseEntity = baseEntity;
229
            this.button = button;
230
        }
231

    
232
        public VersionableEntity getBaseEntity() {
233
            return baseEntity;
234
        }
235

    
236
        public Button getButton() {
237
            return button;
238
        }
239

    
240
        public TypeDesignationSetType getType() {
241
            return type;
242
        }
243
    }
244

    
245
    public class IdButton<T> {
246
        private UUID uuid;
247
        private Class<T> entityType;
248
        private Button button;
249

    
250
        public IdButton(Class<T> type, UUID uuid, Button button){
251
            this.entityType = type;
252
            this.uuid = uuid;
253
            this.button = button;
254
        }
255

    
256
        public UUID getUuid() {
257
            return uuid;
258
        }
259

    
260
        public Button getButton() {
261
            return button;
262
        }
263

    
264
        public Class<T> getType() {
265
            return entityType;
266
        }
267
    }
268

    
269
    public class ButtonWithUserEditPermission {
270

    
271
        Button button;
272
        boolean userCanEdit;
273
        public ButtonWithUserEditPermission(Button button, boolean userCanEdit) {
274
            super();
275
            this.button = button;
276
            this.userCanEdit = userCanEdit;
277
        }
278
    }
279

    
280
    public boolean isRegistrationLocked() {
281
        return isRegistrationLocked;
282
    }
283

    
284
    public boolean isLockOverride() {
285
        return isLockOverride;
286
    }
287

    
288
    public void setLockOverride(boolean isLockOverride) {
289
        if(this.isLockOverride != isLockOverride){
290
            this.isLockOverride = isLockOverride;
291
            updateEditorButtonReadonlyStates();
292
        }
293
    }
294

    
295
    private class TypedEntityRefWithStatus implements Comparable<TypedEntityRefWithStatus> {
296

    
297
        public TypedEntityReference<? extends VersionableEntity> typedEntity;
298
        public TypeDesignationStatusBase<?> status;
299
        private RegistrationTypeDesignationStatusComparator comparator = new RegistrationTypeDesignationStatusComparator();
300

    
301
        public TypedEntityRefWithStatus(TypedEntityReference<? extends VersionableEntity> typedEntity,
302
                TypeDesignationStatusBase<?> status) {
303
            this.typedEntity = typedEntity;
304
            this.status = status;
305
        }
306

    
307
        @Override
308
        public int compareTo(TypedEntityRefWithStatus o) {
309
            return comparator.compare(this.status, o.status);
310
        }
311
    }
312
}
(4-4/11)