]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/di/RedmineAERISettingsCreationFunction.java
Experiment around with AERI in Simantics Products
[simantics/platform.git] / bundles / org.simantics.aeri.ui.redmine.core / src / org / simantics / aeri / redmine / core / di / RedmineAERISettingsCreationFunction.java
1 package org.simantics.aeri.redmine.core.di;
2
3 import java.util.HashSet;
4 import java.util.List;
5 import java.util.Set;
6
7 import org.eclipse.core.runtime.preferences.ConfigurationScope;
8 import org.eclipse.core.runtime.preferences.InstanceScope;
9 import org.eclipse.e4.core.contexts.IContextFunction;
10 import org.eclipse.e4.core.contexts.IEclipseContext;
11 import org.eclipse.emf.common.notify.Notification;
12 import org.eclipse.emf.common.notify.impl.AdapterImpl;
13 import org.eclipse.emf.ecore.EAttribute;
14 import org.eclipse.emf.ecore.EClass;
15 import org.eclipse.emf.ecore.EDataType;
16 import org.eclipse.emf.ecore.EStructuralFeature;
17 import org.eclipse.emf.ecore.util.EcoreUtil;
18 import org.eclipse.epp.logging.aeri.core.SystemControl;
19 import org.eclipse.jface.util.IPropertyChangeListener;
20 import org.eclipse.jface.util.PropertyChangeEvent;
21 import org.eclipse.ui.preferences.ScopedPreferenceStore;
22 import org.simantics.aeri.redmine.core.internal.Activator;
23 import org.simantics.aeri.redmine.core.settings.RedmineAERISettings;
24 import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsFactory;
25 import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage;
26
27 import com.google.common.base.Joiner;
28 import com.google.common.base.Splitter;
29 import com.google.common.collect.ImmutableSet;
30
31 /**
32  * Context function that computes the {@link RedmineAERISettings}.
33  */
34 public class RedmineAERISettingsCreationFunction implements IContextFunction {
35
36     @Override
37     public Object compute(IEclipseContext localContext, String contextKey) {
38         RedmineAERISettings settings = RedmineAERISettingsFactory.eINSTANCE.createRedmineAERISettings();
39         EClass eClass = settings.eClass();
40         ScopedPreferenceStore instanceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.BUNDLE_ID);
41         loadFromPreferences(instanceStore, settings, eClass);
42         registerPreferenceStoreChangeListener(instanceStore, settings, eClass);
43         registerSettingsChangeListener(instanceStore, settings, new HashSet<EAttribute>());
44
45         // register a listener that sends selected changes to the configuration scope store:
46         // convenience to allow users with different workspaces to reuse the settings
47         ScopedPreferenceStore configurationStore = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, Activator.BUNDLE_ID);
48         registerSettingsChangeListener(configurationStore, settings,
49                 ImmutableSet.of(RedmineAERISettingsPackage.eINSTANCE.getRedmineAERISettings_ApiKey()));
50
51         // set this settings object in the root context. Effectively replaces this context function.
52         IEclipseContext systemContext = SystemControl.getSystemContext();
53         systemContext.set(contextKey, settings);
54         return settings;
55     }
56
57     private static void registerSettingsChangeListener(final ScopedPreferenceStore store, final RedmineAERISettings settings,
58             final Set<EAttribute> allowedKeys) {
59         settings.eAdapters().add(new AdapterImpl() {
60             @Override
61             public void notifyChanged(Notification msg) {
62                 Object feature = msg.getFeature();
63                 if (!(feature instanceof EAttribute)) {
64                     return;
65                 }
66                 EAttribute attr = (EAttribute) feature;
67                 EDataType type = attr.getEAttributeType();
68                 Object value = msg.getNewValue();
69
70                 // @Nullable
71                 String data = EcoreUtil.convertToString(type, value);
72
73                 // if empty all keys are allowed:
74                 if (allowedKeys.isEmpty() || allowedKeys.contains(attr)) {
75                     try {
76                         // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=494098,
77                         // data may be null and null is not valid as value
78                         if (data == null) {
79                             store.setToDefault(attr.getName());
80                         } else {
81                             store.putValue(attr.getName(), data);
82                         }
83                         store.save();
84                     } catch (Exception e) {
85                         e.printStackTrace();
86 //                        log(ERROR_SAVE_PREFERENCES_FAILED, e, attr.getName(), data);
87                     }
88                 }
89             }
90         });
91     }
92
93     private static void registerPreferenceStoreChangeListener(final ScopedPreferenceStore store, final RedmineAERISettings settings,
94             final EClass eClass) {
95         store.addPropertyChangeListener(new IPropertyChangeListener() {
96
97             @Override
98             public void propertyChange(PropertyChangeEvent event) {
99                 String property = event.getProperty();
100                 EStructuralFeature feature = eClass.getEStructuralFeature(property);
101                 if (feature != null && feature instanceof EAttribute) {
102                     EAttribute attr = (EAttribute) feature;
103                     EDataType type = attr.getEAttributeType();
104                     String string = EcoreUtil.convertToString(type, event.getNewValue());
105                     Object value = EcoreUtil.createFromString(type, string);
106                     settings.eSet(feature, value);
107                 }
108             }
109         });
110     }
111
112     private static void loadFromPreferences(final ScopedPreferenceStore store, final RedmineAERISettings settings, final EClass eClass) {
113         for (EAttribute attr : eClass.getEAllAttributes()) {
114             EDataType type = attr.getEAttributeType();
115             String key = attr.getName();
116             if (!store.contains(key)) {
117                 continue;
118             }
119             String value = store.getString(key);
120             try {
121                 if (attr.isMany()) {
122                     for (String s : convert(value)) {
123                         Object data = EcoreUtil.createFromString(type, s);
124                         ((List<Object>) settings.eGet(attr)).add(data);
125                     }
126                     continue;
127                 }
128                 Object data = EcoreUtil.createFromString(type, value);
129                 settings.eSet(attr, data);
130             } catch (Exception e) {
131                 e.printStackTrace();
132 //                log(ERROR_FAILED_TO_PARSE_PREFERENCE_VALUE, attr, value);
133             }
134         }
135     }
136
137     static List<String> convert(String string) {
138         return Splitter.on(';').omitEmptyStrings().trimResults().splitToList(string);
139
140     }
141
142     static String convert(List<String> strings) {
143         return Joiner.on(';').skipNulls().join(strings);
144     }
145 }