1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.task.app;
35
36 import info.magnolia.cms.security.User;
37 import info.magnolia.context.Context;
38 import info.magnolia.objectfactory.Components;
39 import info.magnolia.task.Task;
40 import info.magnolia.ui.datasource.PropertySetFactory;
41 import info.magnolia.ui.field.FieldDefinition;
42 import info.magnolia.ui.framework.util.TimezoneUtil;
43
44 import java.time.Instant;
45 import java.time.ZonedDateTime;
46 import java.time.format.DateTimeFormatter;
47 import java.util.Calendar;
48 import java.util.Collection;
49 import java.util.Collections;
50 import java.util.HashMap;
51 import java.util.Locale;
52 import java.util.Map;
53 import java.util.Optional;
54 import java.util.stream.Stream;
55
56 import javax.inject.Inject;
57
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.time.FastDateFormat;
60
61 import com.vaadin.data.BeanPropertySet;
62 import com.vaadin.data.PropertyDefinition;
63 import com.vaadin.data.PropertySet;
64 import com.vaadin.data.ValueProvider;
65 import com.vaadin.server.Setter;
66
67 import lombok.AllArgsConstructor;
68
69
70
71
72 public class TasksPropertySetFactory implements PropertySetFactory<Task> {
73
74 private final User user;
75
76 @Inject
77 TasksPropertySetFactory(Context context) {
78 this.user = context.getUser();
79 }
80
81
82
83
84 @Deprecated
85 public TasksPropertySetFactory() {
86 this(Components.getComponent(Context.class));
87 }
88
89 @Override
90 public PropertySet<Task> withProperties(Map<String, Class> properties) {
91 return getPropertySet(Collections.emptyList());
92 }
93
94 @Override
95 public PropertySet<Task> fromFieldDefinitions(Collection<FieldDefinition> fieldDefinitions, Locale locale) {
96 return getPropertySet(fieldDefinitions);
97 }
98
99 private PropertySet<Task> getPropertySet(Collection<FieldDefinition> fieldDefinitions) {
100 return new PropertySet<Task>() {
101 private final PropertySet<Task> propertySet = BeanPropertySet.get(Task.class);
102
103 @Override
104 public Stream<PropertyDefinition<Task, ?>> getProperties() {
105 return (fieldDefinitions.isEmpty())
106 ? propertySet.getProperties().map(propertyDefinition -> new TaskPropertyDefinition(propertySet, propertyDefinition.getName()))
107 : fieldDefinitions.stream().map(editorPropertyDefinition -> new TaskPropertyDefinition(propertySet, editorPropertyDefinition.getName()));
108 }
109
110 @Override
111 public Optional<PropertyDefinition<Task, ?>> getProperty(String name) {
112 return getProperties().filter(taskPropertyDefinition -> taskPropertyDefinition.getName().equals(name)).findFirst();
113 }
114 };
115 }
116
117 @AllArgsConstructor
118 private class TaskPropertyDefinition implements PropertyDefinition<Task, Object> {
119 private final PropertySet<Task> propertySet;
120 private final String name;
121
122 @Override
123 public ValueProvider<Task, Object> getGetter() {
124 return name.contains(".") ? getTaskObjectValueProvider() : (ValueProvider<Task, Object>) propertySet.getProperty(name).map(PropertyDefinition::getGetter).get();
125 }
126
127 private ValueProvider<Task, Object> getTaskObjectValueProvider() {
128 return task -> {
129 Map<?, ?> subPropertySet = propertySet.getProperty(StringUtils.substringBefore(name, "."))
130 .map(PropertyDefinition::getGetter)
131 .map(taskValueProvider -> taskValueProvider.apply(task))
132 .filter(Map.class::isInstance)
133 .map(Map.class::cast)
134 .orElse(new HashMap<>());
135
136 return Optional.ofNullable(subPropertySet.get(StringUtils.substringAfter(name, ".")))
137 .map(object -> object instanceof Calendar ? getZonedDateTime(((Calendar) object).getTimeInMillis()).format(DateTimeFormatter.ofPattern(getDateTimePattern())) : String.valueOf(object))
138 .orElse(StringUtils.EMPTY);
139 };
140 }
141
142 private String getDateTimePattern() {
143 Locale locale = TimezoneUtil.getUserLocale(user);
144 return FastDateFormat.getDateTimeInstance(FastDateFormat.MEDIUM, FastDateFormat.FULL, locale).getPattern();
145 }
146
147 private ZonedDateTime getZonedDateTime(long ms) {
148 return Instant.ofEpochMilli(ms)
149 .atZone(TimezoneUtil.getUserZoneId(user));
150 }
151
152 @Override
153 public Optional<Setter<Task, Object>> getSetter() {
154 return Optional.empty();
155 }
156
157 @Override
158 public Class<Object> getType() {
159 return Object.class;
160 }
161
162 public Class<?> getPropertyHolderType() {
163 return Task.class;
164 }
165
166 @Override
167 public String getName() {
168 return name;
169 }
170
171 @Override
172 public PropertySet<Task> getPropertySet() {
173 return propertySet;
174 }
175
176 @Override
177 public String getCaption() {
178 return name.toUpperCase();
179 }
180
181 }
182
183 }
184