]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Experiment around with AERI in Simantics Products private/jsimomaa-aeri
authorjsimomaa <jani.simomaa@gmail.com>
Wed, 4 Jan 2017 11:10:17 +0000 (13:10 +0200)
committerjsimomaa <jani.simomaa@gmail.com>
Wed, 4 Jan 2017 11:53:16 +0000 (13:53 +0200)
refs #6935

Change-Id: Idcd617129e21d6836865cd2ab40bbd3dc074db59

39 files changed:
bundles/org.simantics.aeri.ui.redmine.core/.classpath [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/.gitignore [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/.project [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/build.properties [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.ecore [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.genmodel [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/plugin.properties [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/plugin.xml [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/di/RedmineAERISettingsCreationFunction.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/internal/Activator.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettings.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsFactory.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsPackage.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsFactoryImpl.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsImpl.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsPackageImpl.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsAdapterFactory.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsSwitch.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/.classpath [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/.gitignore [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/.project [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/build.properties [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon16.png [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon32.png [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/lib/json-20090211.jar [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0-sources.jar [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0.jar [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/plugin.xml [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineCredentialsDialog.java [new file with mode: 0644]
bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineServerConnection.java [new file with mode: 0644]
bundles/org.simantics.desktop.product/simantics-desktop.product
features/org.simantics.aeri.ui.feature/.project [new file with mode: 0644]
features/org.simantics.aeri.ui.feature/build.properties [new file with mode: 0644]
features/org.simantics.aeri.ui.feature/feature.xml [new file with mode: 0644]
releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target

diff --git a/bundles/org.simantics.aeri.ui.redmine.core/.classpath b/bundles/org.simantics.aeri.ui.redmine.core/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/.gitignore b/bundles/org.simantics.aeri.ui.redmine.core/.gitignore
new file mode 100644 (file)
index 0000000..ae3c172
--- /dev/null
@@ -0,0 +1 @@
+/bin/
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/.project b/bundles/org.simantics.aeri.ui.redmine.core/.project
new file mode 100644 (file)
index 0000000..67ba378
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.aeri.ui.redmine.core</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.aeri.ui.redmine.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/META-INF/MANIFEST.MF b/bundles/org.simantics.aeri.ui.redmine.core/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..2bac6bc
--- /dev/null
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.simantics.aeri.ui.redmine.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: org.simantics.aeri.redmine.core.settings,
+ org.simantics.aeri.redmine.core.settings.impl,
+ org.simantics.aeri.redmine.core.settings.util
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.e4.core.contexts,
+ org.eclipse.ui.workbench,
+ org.eclipse.jface,
+ com.google.guava;bundle-version="15.0.0",
+ org.eclipse.epp.logging.aeri.core
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.simantics.aeri.redmine.core.internal.Activator
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/build.properties b/bundles/org.simantics.aeri.ui.redmine.core/build.properties
new file mode 100644 (file)
index 0000000..4d3b182
--- /dev/null
@@ -0,0 +1,10 @@
+#\r
+\r
+bin.includes = .,\\r
+               model/,\\r
+               META-INF/,\\r
+               plugin.xml,\\r
+               plugin.properties\r
+jars.compile.order = .\r
+source.. = src/\r
+output.. = bin/\r
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.ecore b/bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.ecore
new file mode 100644 (file)
index 0000000..f3f97cd
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="settings" nsURI="http://www.simantics.org/emf/redmine-aeri-settings"\r
+    nsPrefix="RedmineAERISettings">\r
+  <eClassifiers xsi:type="ecore:EClass" name="RedmineAERISettings">\r
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="apiKey" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>\r
+  </eClassifiers>\r
+</ecore:EPackage>\r
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.genmodel b/bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.genmodel
new file mode 100644 (file)
index 0000000..f6bc663
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"\r
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.simantics.aeri.redmine.core/src" modelPluginID="org.simantics.aeri.redmine.core"\r
+    modelName="RedmineAERISettings" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container"\r
+    importerID="org.eclipse.emf.importer.ecore" complianceLevel="8.0" copyrightFields="false"\r
+    operationReflection="true" importOrganizing="true">\r
+  <foreignModel>RedmineAERISettings.ecore</foreignModel>\r
+  <genPackages prefix="RedmineAERISettings" basePackage="org.simantics.aeri.redmine.core"\r
+      disposableProviderFactory="true" ecorePackage="RedmineAERISettings.ecore#/">\r
+    <genClasses ecoreClass="RedmineAERISettings.ecore#//RedmineAERISettings">\r
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute RedmineAERISettings.ecore#//RedmineAERISettings/apiKey"/>\r
+    </genClasses>\r
+  </genPackages>\r
+</genmodel:GenModel>\r
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/plugin.properties b/bundles/org.simantics.aeri.ui.redmine.core/plugin.properties
new file mode 100644 (file)
index 0000000..037e1d1
--- /dev/null
@@ -0,0 +1,4 @@
+#\r
+\r
+pluginName = RedmineAERISettings Model\r
+providerName = www.example.org\r
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/plugin.xml b/bundles/org.simantics.aeri.ui.redmine.core/plugin.xml
new file mode 100644 (file)
index 0000000..4526278
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<!--
+-->
+
+<plugin>
+
+   <extension point="org.eclipse.emf.ecore.generated_package">
+      <!-- @generated RedmineAERISettings -->
+      <package
+            uri="http://www.simantics.org/emf/redmine-aeri-settings"
+            class="org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage"
+            genModel="model/RedmineAERISettings.genmodel"/>
+   </extension>
+
+</plugin>
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/di/RedmineAERISettingsCreationFunction.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/di/RedmineAERISettingsCreationFunction.java
new file mode 100644 (file)
index 0000000..a1cd85f
--- /dev/null
@@ -0,0 +1,145 @@
+package org.simantics.aeri.redmine.core.di;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.preferences.ConfigurationScope;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.e4.core.contexts.IContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.epp.logging.aeri.core.SystemControl;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.simantics.aeri.redmine.core.internal.Activator;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettings;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsFactory;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Context function that computes the {@link RedmineAERISettings}.
+ */
+public class RedmineAERISettingsCreationFunction implements IContextFunction {
+
+    @Override
+    public Object compute(IEclipseContext localContext, String contextKey) {
+        RedmineAERISettings settings = RedmineAERISettingsFactory.eINSTANCE.createRedmineAERISettings();
+        EClass eClass = settings.eClass();
+        ScopedPreferenceStore instanceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.BUNDLE_ID);
+        loadFromPreferences(instanceStore, settings, eClass);
+        registerPreferenceStoreChangeListener(instanceStore, settings, eClass);
+        registerSettingsChangeListener(instanceStore, settings, new HashSet<EAttribute>());
+
+        // register a listener that sends selected changes to the configuration scope store:
+        // convenience to allow users with different workspaces to reuse the settings
+        ScopedPreferenceStore configurationStore = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, Activator.BUNDLE_ID);
+        registerSettingsChangeListener(configurationStore, settings,
+                ImmutableSet.of(RedmineAERISettingsPackage.eINSTANCE.getRedmineAERISettings_ApiKey()));
+
+        // set this settings object in the root context. Effectively replaces this context function.
+        IEclipseContext systemContext = SystemControl.getSystemContext();
+        systemContext.set(contextKey, settings);
+        return settings;
+    }
+
+    private static void registerSettingsChangeListener(final ScopedPreferenceStore store, final RedmineAERISettings settings,
+            final Set<EAttribute> allowedKeys) {
+        settings.eAdapters().add(new AdapterImpl() {
+            @Override
+            public void notifyChanged(Notification msg) {
+                Object feature = msg.getFeature();
+                if (!(feature instanceof EAttribute)) {
+                    return;
+                }
+                EAttribute attr = (EAttribute) feature;
+                EDataType type = attr.getEAttributeType();
+                Object value = msg.getNewValue();
+
+                // @Nullable
+                String data = EcoreUtil.convertToString(type, value);
+
+                // if empty all keys are allowed:
+                if (allowedKeys.isEmpty() || allowedKeys.contains(attr)) {
+                    try {
+                        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=494098,
+                        // data may be null and null is not valid as value
+                        if (data == null) {
+                            store.setToDefault(attr.getName());
+                        } else {
+                            store.putValue(attr.getName(), data);
+                        }
+                        store.save();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+//                        log(ERROR_SAVE_PREFERENCES_FAILED, e, attr.getName(), data);
+                    }
+                }
+            }
+        });
+    }
+
+    private static void registerPreferenceStoreChangeListener(final ScopedPreferenceStore store, final RedmineAERISettings settings,
+            final EClass eClass) {
+        store.addPropertyChangeListener(new IPropertyChangeListener() {
+
+            @Override
+            public void propertyChange(PropertyChangeEvent event) {
+                String property = event.getProperty();
+                EStructuralFeature feature = eClass.getEStructuralFeature(property);
+                if (feature != null && feature instanceof EAttribute) {
+                    EAttribute attr = (EAttribute) feature;
+                    EDataType type = attr.getEAttributeType();
+                    String string = EcoreUtil.convertToString(type, event.getNewValue());
+                    Object value = EcoreUtil.createFromString(type, string);
+                    settings.eSet(feature, value);
+                }
+            }
+        });
+    }
+
+    private static void loadFromPreferences(final ScopedPreferenceStore store, final RedmineAERISettings settings, final EClass eClass) {
+        for (EAttribute attr : eClass.getEAllAttributes()) {
+            EDataType type = attr.getEAttributeType();
+            String key = attr.getName();
+            if (!store.contains(key)) {
+                continue;
+            }
+            String value = store.getString(key);
+            try {
+                if (attr.isMany()) {
+                    for (String s : convert(value)) {
+                        Object data = EcoreUtil.createFromString(type, s);
+                        ((List<Object>) settings.eGet(attr)).add(data);
+                    }
+                    continue;
+                }
+                Object data = EcoreUtil.createFromString(type, value);
+                settings.eSet(attr, data);
+            } catch (Exception e) {
+                e.printStackTrace();
+//                log(ERROR_FAILED_TO_PARSE_PREFERENCE_VALUE, attr, value);
+            }
+        }
+    }
+
+    static List<String> convert(String string) {
+        return Splitter.on(';').omitEmptyStrings().trimResults().splitToList(string);
+
+    }
+
+    static String convert(List<String> strings) {
+        return Joiner.on(';').skipNulls().join(strings);
+    }
+}
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/internal/Activator.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/internal/Activator.java
new file mode 100644 (file)
index 0000000..705c02d
--- /dev/null
@@ -0,0 +1,24 @@
+package org.simantics.aeri.redmine.core.internal;
+
+import org.eclipse.epp.logging.aeri.core.SystemControl;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.simantics.aeri.redmine.core.di.RedmineAERISettingsCreationFunction;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettings;
+
+public class Activator implements BundleActivator {
+
+    public static final String BUNDLE_ID = "org.simantics.aeri.redmine.core"; //$NON-NLS-1$
+    
+    @Override
+    public void start(BundleContext context) throws Exception {
+        SystemControl.getSystemContext().set(RedmineAERISettings.class.getName(), new RedmineAERISettingsCreationFunction());
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        // TODO Auto-generated method stub
+
+    }
+
+}
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettings.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettings.java
new file mode 100644 (file)
index 0000000..98e5aaf
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Redmine AERI Settings</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * </p>
+ * <ul>
+ *   <li>{@link org.simantics.aeri.redmine.core.settings.RedmineAERISettings#getApiKey <em>Api Key</em>}</li>
+ * </ul>
+ *
+ * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage#getRedmineAERISettings()
+ * @model
+ * @generated
+ */
+public interface RedmineAERISettings extends EObject {
+    /**
+     * Returns the value of the '<em><b>Api Key</b></em>' attribute.
+     * <!-- begin-user-doc -->
+     * <p>
+     * If the meaning of the '<em>Api Key</em>' attribute isn't clear,
+     * there really should be more of a description here...
+     * </p>
+     * <!-- end-user-doc -->
+     * @return the value of the '<em>Api Key</em>' attribute.
+     * @see #setApiKey(String)
+     * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage#getRedmineAERISettings_ApiKey()
+     * @model
+     * @generated
+     */
+    String getApiKey();
+
+    /**
+     * Sets the value of the '{@link org.simantics.aeri.redmine.core.settings.RedmineAERISettings#getApiKey <em>Api Key</em>}' attribute.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @param value the new value of the '<em>Api Key</em>' attribute.
+     * @see #getApiKey()
+     * @generated
+     */
+    void setApiKey(String value);
+
+} // RedmineAERISettings
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsFactory.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsFactory.java
new file mode 100644 (file)
index 0000000..6204837
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings;
+
+import org.eclipse.emf.ecore.EFactory;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Factory</b> for the model.
+ * It provides a create method for each non-abstract class of the model.
+ * <!-- end-user-doc -->
+ * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage
+ * @generated
+ */
+public interface RedmineAERISettingsFactory extends EFactory {
+    /**
+     * The singleton instance of the factory.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    RedmineAERISettingsFactory eINSTANCE = org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsFactoryImpl.init();
+
+    /**
+     * Returns a new object of class '<em>Redmine AERI Settings</em>'.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @return a new object of class '<em>Redmine AERI Settings</em>'.
+     * @generated
+     */
+    RedmineAERISettings createRedmineAERISettings();
+
+    /**
+     * Returns the package supported by this factory.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @return the package supported by this factory.
+     * @generated
+     */
+    RedmineAERISettingsPackage getRedmineAERISettingsPackage();
+
+} //RedmineAERISettingsFactory
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsPackage.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsPackage.java
new file mode 100644 (file)
index 0000000..07d84ae
--- /dev/null
@@ -0,0 +1,160 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Package</b> for the model.
+ * It contains accessors for the meta objects to represent
+ * <ul>
+ *   <li>each class,</li>
+ *   <li>each feature of each class,</li>
+ *   <li>each operation of each class,</li>
+ *   <li>each enum,</li>
+ *   <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsFactory
+ * @model kind="package"
+ * @generated
+ */
+public interface RedmineAERISettingsPackage extends EPackage {
+    /**
+     * The package name.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    String eNAME = "settings";
+
+    /**
+     * The package namespace URI.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    String eNS_URI = "http://www.simantics.org/emf/redmine-aeri-settings";
+
+    /**
+     * The package namespace name.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    String eNS_PREFIX = "RedmineAERISettings";
+
+    /**
+     * The singleton instance of the package.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    RedmineAERISettingsPackage eINSTANCE = org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsPackageImpl.init();
+
+    /**
+     * The meta object id for the '{@link org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsImpl <em>Redmine AERI Settings</em>}' class.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @see org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsImpl
+     * @see org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsPackageImpl#getRedmineAERISettings()
+     * @generated
+     */
+    int REDMINE_AERI_SETTINGS = 0;
+
+    /**
+     * The feature id for the '<em><b>Api Key</b></em>' attribute.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     * @ordered
+     */
+    int REDMINE_AERI_SETTINGS__API_KEY = 0;
+
+    /**
+     * The number of structural features of the '<em>Redmine AERI Settings</em>' class.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     * @ordered
+     */
+    int REDMINE_AERI_SETTINGS_FEATURE_COUNT = 1;
+
+    /**
+     * The number of operations of the '<em>Redmine AERI Settings</em>' class.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     * @ordered
+     */
+    int REDMINE_AERI_SETTINGS_OPERATION_COUNT = 0;
+
+
+    /**
+     * Returns the meta object for class '{@link org.simantics.aeri.redmine.core.settings.RedmineAERISettings <em>Redmine AERI Settings</em>}'.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @return the meta object for class '<em>Redmine AERI Settings</em>'.
+     * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettings
+     * @generated
+     */
+    EClass getRedmineAERISettings();
+
+    /**
+     * Returns the meta object for the attribute '{@link org.simantics.aeri.redmine.core.settings.RedmineAERISettings#getApiKey <em>Api Key</em>}'.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @return the meta object for the attribute '<em>Api Key</em>'.
+     * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettings#getApiKey()
+     * @see #getRedmineAERISettings()
+     * @generated
+     */
+    EAttribute getRedmineAERISettings_ApiKey();
+
+    /**
+     * Returns the factory that creates the instances of the model.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @return the factory that creates the instances of the model.
+     * @generated
+     */
+    RedmineAERISettingsFactory getRedmineAERISettingsFactory();
+
+    /**
+     * <!-- begin-user-doc -->
+     * Defines literals for the meta objects that represent
+     * <ul>
+     *   <li>each class,</li>
+     *   <li>each feature of each class,</li>
+     *   <li>each operation of each class,</li>
+     *   <li>each enum,</li>
+     *   <li>and each data type</li>
+     * </ul>
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    interface Literals {
+        /**
+         * The meta object literal for the '{@link org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsImpl <em>Redmine AERI Settings</em>}' class.
+         * <!-- begin-user-doc -->
+         * <!-- end-user-doc -->
+         * @see org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsImpl
+         * @see org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsPackageImpl#getRedmineAERISettings()
+         * @generated
+         */
+        EClass REDMINE_AERI_SETTINGS = eINSTANCE.getRedmineAERISettings();
+
+        /**
+         * The meta object literal for the '<em><b>Api Key</b></em>' attribute feature.
+         * <!-- begin-user-doc -->
+         * <!-- end-user-doc -->
+         * @generated
+         */
+        EAttribute REDMINE_AERI_SETTINGS__API_KEY = eINSTANCE.getRedmineAERISettings_ApiKey();
+
+    }
+
+} //RedmineAERISettingsPackage
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsFactoryImpl.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsFactoryImpl.java
new file mode 100644 (file)
index 0000000..9dcdc83
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings.impl;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+
+import org.eclipse.emf.ecore.impl.EFactoryImpl;
+
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+
+import org.simantics.aeri.redmine.core.settings.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Factory</b>.
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public class RedmineAERISettingsFactoryImpl extends EFactoryImpl implements RedmineAERISettingsFactory {
+    /**
+     * Creates the default factory implementation.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public static RedmineAERISettingsFactory init() {
+        try {
+            RedmineAERISettingsFactory theRedmineAERISettingsFactory = (RedmineAERISettingsFactory)EPackage.Registry.INSTANCE.getEFactory(RedmineAERISettingsPackage.eNS_URI);
+            if (theRedmineAERISettingsFactory != null) {
+                return theRedmineAERISettingsFactory;
+            }
+        }
+        catch (Exception exception) {
+            EcorePlugin.INSTANCE.log(exception);
+        }
+        return new RedmineAERISettingsFactoryImpl();
+    }
+
+    /**
+     * Creates an instance of the factory.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public RedmineAERISettingsFactoryImpl() {
+        super();
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    @Override
+    public EObject create(EClass eClass) {
+        switch (eClass.getClassifierID()) {
+            case RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS: return createRedmineAERISettings();
+            default:
+                throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
+        }
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public RedmineAERISettings createRedmineAERISettings() {
+        RedmineAERISettingsImpl redmineAERISettings = new RedmineAERISettingsImpl();
+        return redmineAERISettings;
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public RedmineAERISettingsPackage getRedmineAERISettingsPackage() {
+        return (RedmineAERISettingsPackage)getEPackage();
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @deprecated
+     * @generated
+     */
+    @Deprecated
+    public static RedmineAERISettingsPackage getPackage() {
+        return RedmineAERISettingsPackage.eINSTANCE;
+    }
+
+} //RedmineAERISettingsFactoryImpl
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsImpl.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsImpl.java
new file mode 100644 (file)
index 0000000..e2990c1
--- /dev/null
@@ -0,0 +1,163 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings.impl;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
+
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettings;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Redmine AERI Settings</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * </p>
+ * <ul>
+ *   <li>{@link org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsImpl#getApiKey <em>Api Key</em>}</li>
+ * </ul>
+ *
+ * @generated
+ */
+public class RedmineAERISettingsImpl extends MinimalEObjectImpl.Container implements RedmineAERISettings {
+    /**
+     * The default value of the '{@link #getApiKey() <em>Api Key</em>}' attribute.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @see #getApiKey()
+     * @generated
+     * @ordered
+     */
+    protected static final String API_KEY_EDEFAULT = null;
+
+    /**
+     * The cached value of the '{@link #getApiKey() <em>Api Key</em>}' attribute.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @see #getApiKey()
+     * @generated
+     * @ordered
+     */
+    protected String apiKey = API_KEY_EDEFAULT;
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    protected RedmineAERISettingsImpl() {
+        super();
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    @Override
+    protected EClass eStaticClass() {
+        return RedmineAERISettingsPackage.Literals.REDMINE_AERI_SETTINGS;
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public void setApiKey(String newApiKey) {
+        String oldApiKey = apiKey;
+        apiKey = newApiKey;
+        if (eNotificationRequired())
+            eNotify(new ENotificationImpl(this, Notification.SET, RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS__API_KEY, oldApiKey, apiKey));
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    @Override
+    public Object eGet(int featureID, boolean resolve, boolean coreType) {
+        switch (featureID) {
+            case RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS__API_KEY:
+                return getApiKey();
+        }
+        return super.eGet(featureID, resolve, coreType);
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    @Override
+    public void eSet(int featureID, Object newValue) {
+        switch (featureID) {
+            case RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS__API_KEY:
+                setApiKey((String)newValue);
+                return;
+        }
+        super.eSet(featureID, newValue);
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    @Override
+    public void eUnset(int featureID) {
+        switch (featureID) {
+            case RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS__API_KEY:
+                setApiKey(API_KEY_EDEFAULT);
+                return;
+        }
+        super.eUnset(featureID);
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    @Override
+    public boolean eIsSet(int featureID) {
+        switch (featureID) {
+            case RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS__API_KEY:
+                return API_KEY_EDEFAULT == null ? apiKey != null : !API_KEY_EDEFAULT.equals(apiKey);
+        }
+        return super.eIsSet(featureID);
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    @Override
+    public String toString() {
+        if (eIsProxy()) return super.toString();
+
+        StringBuffer result = new StringBuffer(super.toString());
+        result.append(" (apiKey: ");
+        result.append(apiKey);
+        result.append(')');
+        return result.toString();
+    }
+
+} //RedmineAERISettingsImpl
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsPackageImpl.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsPackageImpl.java
new file mode 100644 (file)
index 0000000..d9bf645
--- /dev/null
@@ -0,0 +1,177 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings.impl;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettings;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsFactory;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Package</b>.
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public class RedmineAERISettingsPackageImpl extends EPackageImpl implements RedmineAERISettingsPackage {
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    private EClass redmineAERISettingsEClass = null;
+
+    /**
+     * Creates an instance of the model <b>Package</b>, registered with
+     * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
+     * package URI value.
+     * <p>Note: the correct way to create the package is via the static
+     * factory method {@link #init init()}, which also performs
+     * initialization of the package, or returns the registered package,
+     * if one already exists.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @see org.eclipse.emf.ecore.EPackage.Registry
+     * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage#eNS_URI
+     * @see #init()
+     * @generated
+     */
+    private RedmineAERISettingsPackageImpl() {
+        super(eNS_URI, RedmineAERISettingsFactory.eINSTANCE);
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    private static boolean isInited = false;
+
+    /**
+     * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
+     * 
+     * <p>This method is used to initialize {@link RedmineAERISettingsPackage#eINSTANCE} when that field is accessed.
+     * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @see #eNS_URI
+     * @see #createPackageContents()
+     * @see #initializePackageContents()
+     * @generated
+     */
+    public static RedmineAERISettingsPackage init() {
+        if (isInited) return (RedmineAERISettingsPackage)EPackage.Registry.INSTANCE.getEPackage(RedmineAERISettingsPackage.eNS_URI);
+
+        // Obtain or create and register package
+        RedmineAERISettingsPackageImpl theRedmineAERISettingsPackage = (RedmineAERISettingsPackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof RedmineAERISettingsPackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new RedmineAERISettingsPackageImpl());
+
+        isInited = true;
+
+        // Create package meta-data objects
+        theRedmineAERISettingsPackage.createPackageContents();
+
+        // Initialize created meta-data
+        theRedmineAERISettingsPackage.initializePackageContents();
+
+        // Mark meta-data to indicate it can't be changed
+        theRedmineAERISettingsPackage.freeze();
+
+  
+        // Update the registry and return the package
+        EPackage.Registry.INSTANCE.put(RedmineAERISettingsPackage.eNS_URI, theRedmineAERISettingsPackage);
+        return theRedmineAERISettingsPackage;
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public EClass getRedmineAERISettings() {
+        return redmineAERISettingsEClass;
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public EAttribute getRedmineAERISettings_ApiKey() {
+        return (EAttribute)redmineAERISettingsEClass.getEStructuralFeatures().get(0);
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public RedmineAERISettingsFactory getRedmineAERISettingsFactory() {
+        return (RedmineAERISettingsFactory)getEFactoryInstance();
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    private boolean isCreated = false;
+
+    /**
+     * Creates the meta-model objects for the package.  This method is
+     * guarded to have no affect on any invocation but its first.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public void createPackageContents() {
+        if (isCreated) return;
+        isCreated = true;
+
+        // Create classes and their features
+        redmineAERISettingsEClass = createEClass(REDMINE_AERI_SETTINGS);
+        createEAttribute(redmineAERISettingsEClass, REDMINE_AERI_SETTINGS__API_KEY);
+    }
+
+    /**
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    private boolean isInitialized = false;
+
+    /**
+     * Complete the initialization of the package and its meta-model.  This
+     * method is guarded to have no affect on any invocation but its first.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public void initializePackageContents() {
+        if (isInitialized) return;
+        isInitialized = true;
+
+        // Initialize package
+        setName(eNAME);
+        setNsPrefix(eNS_PREFIX);
+        setNsURI(eNS_URI);
+
+        // Create type parameters
+
+        // Set bounds for type parameters
+
+        // Add supertypes to classes
+
+        // Initialize classes, features, and operations; add parameters
+        initEClass(redmineAERISettingsEClass, RedmineAERISettings.class, "RedmineAERISettings", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+        initEAttribute(getRedmineAERISettings_ApiKey(), ecorePackage.getEString(), "apiKey", null, 0, 1, RedmineAERISettings.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+        // Create resource
+        createResource(eNS_URI);
+    }
+
+} //RedmineAERISettingsPackageImpl
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsAdapterFactory.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsAdapterFactory.java
new file mode 100644 (file)
index 0000000..3415cbf
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings.util;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+
+import org.eclipse.emf.ecore.EObject;
+
+import org.simantics.aeri.redmine.core.settings.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Adapter Factory</b> for the model.
+ * It provides an adapter <code>createXXX</code> method for each class of the model.
+ * <!-- end-user-doc -->
+ * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage
+ * @generated
+ */
+public class RedmineAERISettingsAdapterFactory extends AdapterFactoryImpl {
+    /**
+     * The cached model package.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    protected static RedmineAERISettingsPackage modelPackage;
+
+    /**
+     * Creates an instance of the adapter factory.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public RedmineAERISettingsAdapterFactory() {
+        if (modelPackage == null) {
+            modelPackage = RedmineAERISettingsPackage.eINSTANCE;
+        }
+    }
+
+    /**
+     * Returns whether this factory is applicable for the type of the object.
+     * <!-- begin-user-doc -->
+     * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model.
+     * <!-- end-user-doc -->
+     * @return whether this factory is applicable for the type of the object.
+     * @generated
+     */
+    @Override
+    public boolean isFactoryForType(Object object) {
+        if (object == modelPackage) {
+            return true;
+        }
+        if (object instanceof EObject) {
+            return ((EObject)object).eClass().getEPackage() == modelPackage;
+        }
+        return false;
+    }
+
+    /**
+     * The switch that delegates to the <code>createXXX</code> methods.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    protected RedmineAERISettingsSwitch<Adapter> modelSwitch =
+        new RedmineAERISettingsSwitch<Adapter>() {
+            @Override
+            public Adapter caseRedmineAERISettings(RedmineAERISettings object) {
+                return createRedmineAERISettingsAdapter();
+            }
+            @Override
+            public Adapter defaultCase(EObject object) {
+                return createEObjectAdapter();
+            }
+        };
+
+    /**
+     * Creates an adapter for the <code>target</code>.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @param target the object to adapt.
+     * @return the adapter for the <code>target</code>.
+     * @generated
+     */
+    @Override
+    public Adapter createAdapter(Notifier target) {
+        return modelSwitch.doSwitch((EObject)target);
+    }
+
+
+    /**
+     * Creates a new adapter for an object of class '{@link org.simantics.aeri.redmine.core.settings.RedmineAERISettings <em>Redmine AERI Settings</em>}'.
+     * <!-- begin-user-doc -->
+     * This default implementation returns null so that we can easily ignore cases;
+     * it's useful to ignore a case when inheritance will catch all the cases anyway.
+     * <!-- end-user-doc -->
+     * @return the new adapter.
+     * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettings
+     * @generated
+     */
+    public Adapter createRedmineAERISettingsAdapter() {
+        return null;
+    }
+
+    /**
+     * Creates a new adapter for the default case.
+     * <!-- begin-user-doc -->
+     * This default implementation returns null.
+     * <!-- end-user-doc -->
+     * @return the new adapter.
+     * @generated
+     */
+    public Adapter createEObjectAdapter() {
+        return null;
+    }
+
+} //RedmineAERISettingsAdapterFactory
diff --git a/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsSwitch.java b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsSwitch.java
new file mode 100644 (file)
index 0000000..86813b3
--- /dev/null
@@ -0,0 +1,110 @@
+/**
+ */
+package org.simantics.aeri.redmine.core.settings.util;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+
+import org.eclipse.emf.ecore.util.Switch;
+
+import org.simantics.aeri.redmine.core.settings.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Switch</b> for the model's inheritance hierarchy.
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)}
+ * to invoke the <code>caseXXX</code> method for each class of the model,
+ * starting with the actual class of the object
+ * and proceeding up the inheritance hierarchy
+ * until a non-null result is returned,
+ * which is the result of the switch.
+ * <!-- end-user-doc -->
+ * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage
+ * @generated
+ */
+public class RedmineAERISettingsSwitch<T> extends Switch<T> {
+    /**
+     * The cached model package
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    protected static RedmineAERISettingsPackage modelPackage;
+
+    /**
+     * Creates an instance of the switch.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @generated
+     */
+    public RedmineAERISettingsSwitch() {
+        if (modelPackage == null) {
+            modelPackage = RedmineAERISettingsPackage.eINSTANCE;
+        }
+    }
+
+    /**
+     * Checks whether this is a switch for the given package.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @param ePackage the package in question.
+     * @return whether this is a switch for the given package.
+     * @generated
+     */
+    @Override
+    protected boolean isSwitchFor(EPackage ePackage) {
+        return ePackage == modelPackage;
+    }
+
+    /**
+     * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+     * <!-- begin-user-doc -->
+     * <!-- end-user-doc -->
+     * @return the first non-null result returned by a <code>caseXXX</code> call.
+     * @generated
+     */
+    @Override
+    protected T doSwitch(int classifierID, EObject theEObject) {
+        switch (classifierID) {
+            case RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS: {
+                RedmineAERISettings redmineAERISettings = (RedmineAERISettings)theEObject;
+                T result = caseRedmineAERISettings(redmineAERISettings);
+                if (result == null) result = defaultCase(theEObject);
+                return result;
+            }
+            default: return defaultCase(theEObject);
+        }
+    }
+
+    /**
+     * Returns the result of interpreting the object as an instance of '<em>Redmine AERI Settings</em>'.
+     * <!-- begin-user-doc -->
+     * This implementation returns null;
+     * returning a non-null result will terminate the switch.
+     * <!-- end-user-doc -->
+     * @param object the target of the switch.
+     * @return the result of interpreting the object as an instance of '<em>Redmine AERI Settings</em>'.
+     * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+     * @generated
+     */
+    public T caseRedmineAERISettings(RedmineAERISettings object) {
+        return null;
+    }
+
+    /**
+     * Returns the result of interpreting the object as an instance of '<em>EObject</em>'.
+     * <!-- begin-user-doc -->
+     * This implementation returns null;
+     * returning a non-null result will terminate the switch, but this is the last case anyway.
+     * <!-- end-user-doc -->
+     * @param object the target of the switch.
+     * @return the result of interpreting the object as an instance of '<em>EObject</em>'.
+     * @see #doSwitch(org.eclipse.emf.ecore.EObject)
+     * @generated
+     */
+    @Override
+    public T defaultCase(EObject object) {
+        return null;
+    }
+
+} //RedmineAERISettingsSwitch
diff --git a/bundles/org.simantics.aeri.ui.redmine/.classpath b/bundles/org.simantics.aeri.ui.redmine/.classpath
new file mode 100644 (file)
index 0000000..b0c7e37
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry exported="true" kind="lib" path="lib/json-20090211.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/redmine-java-api-3.0.0.jar" sourcepath="lib/redmine-java-api-3.0.0-sources.jar"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.aeri.ui.redmine/.gitignore b/bundles/org.simantics.aeri.ui.redmine/.gitignore
new file mode 100644 (file)
index 0000000..ae3c172
--- /dev/null
@@ -0,0 +1 @@
+/bin/
diff --git a/bundles/org.simantics.aeri.ui.redmine/.project b/bundles/org.simantics.aeri.ui.redmine/.project
new file mode 100644 (file)
index 0000000..e04ac98
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.aeri.ui.redmine</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.aeri.ui.redmine/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.aeri.ui.redmine/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/bundles/org.simantics.aeri.ui.redmine/META-INF/MANIFEST.MF b/bundles/org.simantics.aeri.ui.redmine/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..458a7e9
--- /dev/null
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics AERI UI
+Bundle-SymbolicName: org.simantics.aeri.ui.redmine;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-ClassPath: lib/redmine-java-api-3.0.0.jar,
+ lib/json-20090211.jar,
+ .
+Require-Bundle: org.eclipse.epp.logging.aeri.ide,
+ org.eclipse.epp.logging.aeri.core;bundle-version="2.0.3",
+ org.eclipse.core.runtime;bundle-version="3.11.1",
+ org.eclipse.e4.core.contexts;bundle-version="1.4.0",
+ org.eclipse.jface;bundle-version="3.11.1",
+ org.eclipse.emf.common,
+ org.apache.httpcomponents.httpcore;bundle-version="4.3.3",
+ org.apache.httpcomponents.httpclient;bundle-version="4.3.6",
+ org.slf4j.api;bundle-version="1.7.20",
+ org.eclipse.e4.ui.model.workbench;bundle-version="1.1.100.v20150407-1430",
+ org.eclipse.e4.core.di.annotations,
+ org.eclipse.e4.ui.services,
+ org.eclipse.core.databinding;bundle-version="1.5.0",
+ org.eclipse.emf.ecore;bundle-version="2.12.0",
+ org.eclipse.emf.databinding;bundle-version="1.3.0",
+ org.eclipse.jface.databinding;bundle-version="1.7.0",
+ org.eclipse.core.databinding.property;bundle-version="1.5.0",
+ org.eclipse.ui.workbench,
+ org.simantics.aeri.ui.redmine.core,
+ com.google.guava
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/bundles/org.simantics.aeri.ui.redmine/build.properties b/bundles/org.simantics.aeri.ui.redmine/build.properties
new file mode 100644 (file)
index 0000000..63a34a8
--- /dev/null
@@ -0,0 +1,7 @@
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               plugin.xml,\\r
+               lib/redmine-java-api-3.0.0.jar,\\r
+               lib/json-20090211.jar\r
+source.. = src/\r
diff --git a/bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon16.png b/bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon16.png
new file mode 100644 (file)
index 0000000..8a5b3c4
Binary files /dev/null and b/bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon16.png differ
diff --git a/bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon32.png b/bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon32.png
new file mode 100644 (file)
index 0000000..1dbf788
Binary files /dev/null and b/bundles/org.simantics.aeri.ui.redmine/icon/redmine_fluid_icon32.png differ
diff --git a/bundles/org.simantics.aeri.ui.redmine/lib/json-20090211.jar b/bundles/org.simantics.aeri.ui.redmine/lib/json-20090211.jar
new file mode 100644 (file)
index 0000000..ef29094
Binary files /dev/null and b/bundles/org.simantics.aeri.ui.redmine/lib/json-20090211.jar differ
diff --git a/bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0-sources.jar b/bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0-sources.jar
new file mode 100644 (file)
index 0000000..7b565a3
Binary files /dev/null and b/bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0-sources.jar differ
diff --git a/bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0.jar b/bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0.jar
new file mode 100644 (file)
index 0000000..dbd7e13
Binary files /dev/null and b/bundles/org.simantics.aeri.ui.redmine/lib/redmine-java-api-3.0.0.jar differ
diff --git a/bundles/org.simantics.aeri.ui.redmine/plugin.xml b/bundles/org.simantics.aeri.ui.redmine/plugin.xml
new file mode 100644 (file)
index 0000000..eacf43a
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin>
+
+   <extension
+         point="org.eclipse.epp.logging.aeri.ide.servers">
+      <server
+            class="org.simantics.aeri.ui.redmine.RedmineServerConnection"
+            description="Redmine support for AERI"
+            icon16="icon/redmine_fluid_icon16.png"
+            icon32="icon/redmine_fluid_icon32.png"
+            id="org.simantics.aeri.ui.server1"
+            name="Simantics AERI feature">
+         <configure
+               dialog="org.simantics.aeri.ui.redmine.RedmineCredentialsDialog">
+         </configure>
+         <link
+               href="https://www.simantics.org/redmine"
+               rel="org.simantics.aeri.ui.redmine.link"
+               title="Simantics Redmine">
+         </link>
+         <parameter
+               key="org.simantics.aeri.ui.redmine.project_id"
+               value="www-simantics-org">
+         </parameter>
+      </server>
+   </extension>
+
+</plugin>
diff --git a/bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineCredentialsDialog.java b/bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineCredentialsDialog.java
new file mode 100644 (file)
index 0000000..7e84bc9
--- /dev/null
@@ -0,0 +1,324 @@
+package org.simantics.aeri.ui.redmine;
+
+import static org.eclipse.epp.logging.aeri.core.IModelPackage.Literals.USER_SETTINGS__ANONYMIZE_MESSAGES;
+import static org.eclipse.epp.logging.aeri.core.IModelPackage.Literals.USER_SETTINGS__ANONYMIZE_STACK_TRACES;
+import static org.eclipse.epp.logging.aeri.core.util.Links.REL_PRIVACY_POLICY;
+import static org.eclipse.epp.logging.aeri.core.util.Links.REL_TERMS_OF_USE;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.emf.databinding.EMFProperties;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.epp.internal.logging.aeri.ide.IServerDescriptor;
+import org.eclipse.epp.logging.aeri.core.ILink;
+import org.eclipse.epp.logging.aeri.core.ISystemSettings;
+import org.eclipse.epp.logging.aeri.core.util.Formats;
+import org.eclipse.epp.logging.aeri.core.util.Links;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.window.DefaultToolTip;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.browser.IWebBrowser;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettings;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage;
+
+/**
+ * @author jsjani
+ *
+ *  Very much mimicked from <a>org.eclipse.epp.internal.logging.aeri.ide.dialogs.ConfigureServerDialog</a>
+ *
+ */
+public class RedmineCredentialsDialog extends TitleAreaDialog {
+
+    private static final EAttribute REDMINE_SETTINGS__API_KEY = RedmineAERISettingsPackage.eINSTANCE.getRedmineAERISettings_ApiKey();
+
+    private static Map<EAttribute, EAttribute> SYSTEM_SETTINGS_TO_SERVER = systemSettingsToServer();
+        
+    private static Map<EAttribute, EAttribute> systemSettingsToServer() {
+        Map<EAttribute, EAttribute> result = new HashMap<>();
+        result.put(USER_SETTINGS__ANONYMIZE_MESSAGES, USER_SETTINGS__ANONYMIZE_MESSAGES);
+        result.put(USER_SETTINGS__ANONYMIZE_STACK_TRACES, USER_SETTINGS__ANONYMIZE_STACK_TRACES);
+        return result;
+    }
+    
+    private static final String DIALOG_TITLE_CONFIGURE_SERVER = "Configure Error Reporting for {0}";
+    private static final String BUTTON_TEXT_ENABLE = "Enable";
+    private static final String BUTTON_TEXT_DISABLE = "Disable";
+    
+    /**
+     * Return code to indicate a cancel using the esc-button.
+     */
+    public static final int ESC_CANCEL = 42 + 42;
+
+    private static final Point TOOLTIP_DISPLACEMENT = new Point(5, 20);
+    private static final String DIALOG_MESSAGE_CONFIGURE_SERVER = "Configure the default sending and anonymization options for {0}.";
+    private static final String LINK_TEXT_ENABLE_ADMONITION_WITH_TERMS_OF_USE_AND_PRIVACY_POLICY = "";
+    private static final String LINK_TEXT_TERMS_OF_USE = "Terms of Use";
+    private static final String LINK_TEXT_PRIVACY_POLICY = "Privacy Policy";
+    private static final String LINK_TEXT_ENABLE_ADMONITION_WITH_TERMS_OF_USE = "By clicking \u2018Enable\u2019 you agree to the <a href=\"{1}\">{0}</a> of this server.";
+    private static final String GROUP_TEXT_REDMINE_INFORMATION = "Redmine Information";
+    private static final String FIELD_LABEL_API_KEY = "API key:";
+    private static final String FIELD_MESSAGE_API_KEY = "Required. Redmine API key is used to authenticate and identify the reporter.";
+    private static final String FIELD_MESSAGE_REDMINE_URL = "Location of Redmine server.";
+    private static final String TOOLTIP_SETTINGS_EMAIL = "";
+    private static final String FIELD_LABEL_REDMINE_URL = "URL:";
+    private static final String TOOLTIP_SETTINGS_MAKE_STACKTRACE_ANONYMOUS = "";
+    private static final String FIELD_LABEL_ANONYMIZE_STACKTRACES = "Anonymize package, class, and method names";
+    private static final String FIELD_LABEL_ANONYMIZE_MESSAGES = "Anonymize error log messages";
+    private static final String TOOLTIP_SETTINGS_MAKE_MESSAGES_ANONYMOUS = "";
+    private static final String LINK_TEXT_ENABLE_ADMONITION_WITH_PRIVACY_POLICY = "By clicking \u2018Enable\u2019 you agree to the <a href=\"{1}\">{0}</a> of this server.";
+    private static final String GROUP_TEXT_ANONYMIZATION = "Send Options";
+    private static final String REL_REDMINE_LINK = "org.simantics.aeri.ui.redmine.redmine.link";
+    private static int TOOLTIP_MS_HIDE_DELAY = 20000;
+
+    private IServerDescriptor server;
+    private DataBindingContext context;
+
+    private RedmineAERISettings redmineSettings;
+
+    @Inject
+    public RedmineCredentialsDialog(IServerDescriptor server, RedmineAERISettings redmineSettings, ISystemSettings settings,
+            @Named(IServiceConstants.ACTIVE_SHELL) @Optional Shell parentShell, ImageRegistry registry) {
+        super(parentShell);
+        this.server = server;
+        this.redmineSettings = redmineSettings;
+        setHelpAvailable(false);
+        setShellStyle(SWT.SHELL_TRIM | SWT.RESIZE | SWT.SHEET);
+        context = new DataBindingContext();
+        copySystemDefaultsIfUnset(settings, server);
+    }
+    
+    private static void copySystemDefaultsIfUnset(ISystemSettings source, IServerDescriptor target) {
+        for (Entry<EAttribute, EAttribute> entry : SYSTEM_SETTINGS_TO_SERVER.entrySet()) {
+            EAttribute toAttr = entry.getValue();
+            if (!target.eIsSet(toAttr)) {
+                EAttribute fromAttr = entry.getKey();
+                Object value = source.eGet(fromAttr);
+                target.eSet(toAttr, value);
+            }
+        }
+    }
+
+    @Override
+    protected void createButtonsForButtonBar(Composite parent) {
+        createButton(parent, IDialogConstants.OK_ID, BUTTON_TEXT_ENABLE, true);
+        createButton(parent, IDialogConstants.CANCEL_ID, BUTTON_TEXT_DISABLE, false);
+    }
+
+    @Override
+    public void create() {
+        super.create();
+        setTitle(Formats.format(DIALOG_TITLE_CONFIGURE_SERVER, server.getName()));
+        ILink redmineEndpoint = Links.Link(server, REL_REDMINE_LINK);
+        setMessage(Formats.format(DIALOG_MESSAGE_CONFIGURE_SERVER, redmineEndpoint.getTitle()));
+    }
+    
+    @Override
+    protected Control createDialogArea(Composite parent) {
+        Composite container = new Composite(parent, SWT.NONE);
+        GridLayoutFactory.fillDefaults().extendedMargins(5, 5, 5, 0).applyTo(container);
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(container);
+
+        Composite personalGroup = createPersonalGroup(container);
+        GridDataFactory.fillDefaults().indent(0, 10).grab(true, false).applyTo(personalGroup);
+
+        Group makeAnonymousGroup = createAnonymizeGroup(container);
+        GridDataFactory.fillDefaults().indent(0, 5).applyTo(makeAnonymousGroup);
+
+        ILink termsOfUse = Links.Link(server, REL_TERMS_OF_USE);
+        ILink privacyPolicy = Links.Link(server, REL_PRIVACY_POLICY);
+        
+        String legalText = null;
+        if (termsOfUse != null && privacyPolicy != null) {
+            legalText = Formats.format(LINK_TEXT_ENABLE_ADMONITION_WITH_TERMS_OF_USE_AND_PRIVACY_POLICY,
+                    LINK_TEXT_TERMS_OF_USE, termsOfUse.getHref(),
+                    LINK_TEXT_PRIVACY_POLICY, privacyPolicy.getHref());
+        } else if (termsOfUse != null && privacyPolicy == null) {
+            legalText = Formats.format(LINK_TEXT_ENABLE_ADMONITION_WITH_TERMS_OF_USE,
+                    LINK_TEXT_TERMS_OF_USE, termsOfUse.getHref());
+        } else if (termsOfUse == null && privacyPolicy != null) {
+            legalText = Formats.format(LINK_TEXT_ENABLE_ADMONITION_WITH_PRIVACY_POLICY,
+                    LINK_TEXT_PRIVACY_POLICY, privacyPolicy.getHref());
+        }
+        if (legalText != null) {
+            Link termsAndConditions = new Link(container, SWT.NONE);
+            termsAndConditions.setText(legalText);
+            termsAndConditions.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    openInExternalBrowser(e.text);
+                }
+            });
+            GridDataFactory.fillDefaults().indent(10, 10).hint(300, SWT.DEFAULT).align(SWT.FILL, SWT.CENTER).applyTo(termsAndConditions);
+        }
+
+        Dialog.applyDialogFont(container);
+        return container;
+    }
+
+    // TODO Move to UI class. Similar methods in PreferencePage and SystemSettingsPage
+    private Composite createPersonalGroup(Composite parent) {
+        Group personalGroup = new Group(parent, SWT.NONE);
+        personalGroup.setText(GROUP_TEXT_REDMINE_INFORMATION);
+        GridLayoutFactory.fillDefaults().margins(5, 5).numColumns(2).applyTo(personalGroup);
+        {
+            ILink redmineEndpoint = Links.Link(server, REL_REDMINE_LINK);
+            
+            String tooltip = FIELD_MESSAGE_REDMINE_URL + '\n' + TOOLTIP_SETTINGS_EMAIL;
+            Link link = createLabelWithLink(personalGroup, FIELD_LABEL_REDMINE_URL, "<A>" + redmineEndpoint.getHref() + "</A>", tooltip);
+            link.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    openInExternalBrowser(e.text);
+                }
+            });
+        }
+
+        {
+            Text name = createLabelWithText(personalGroup, FIELD_LABEL_API_KEY, FIELD_MESSAGE_API_KEY,
+                    FIELD_MESSAGE_API_KEY);
+            ISWTObservableValue swt = WidgetProperties.text(SWT.Modify).observe(name);
+            IObservableValue emf = EMFProperties.value(REDMINE_SETTINGS__API_KEY).observe(redmineSettings);
+            context.bindValue(swt, emf);
+        }
+        return personalGroup;
+    }
+
+    private Group createAnonymizeGroup(Composite container) {
+        Group makeAnonymousGroup = new Group(container, SWT.SHADOW_ETCHED_IN | SWT.SHADOW_ETCHED_OUT | SWT.SHADOW_IN | SWT.SHADOW_OUT);
+        makeAnonymousGroup.setLayout(new RowLayout(SWT.VERTICAL));
+        makeAnonymousGroup.setText(GROUP_TEXT_ANONYMIZATION);
+        {
+            Button anonStackTraces = createGroupCheckButton(makeAnonymousGroup, FIELD_LABEL_ANONYMIZE_STACKTRACES,
+                    TOOLTIP_SETTINGS_MAKE_STACKTRACE_ANONYMOUS);
+            anonStackTraces.setFocus();
+            IObservableValue swt = WidgetProperties.selection().observe(anonStackTraces);
+            IObservableValue emf = EMFProperties.value(USER_SETTINGS__ANONYMIZE_STACK_TRACES).observe(server);
+            context.bindValue(swt, emf);
+        }
+        {
+            Button anonMessages = createGroupCheckButton(makeAnonymousGroup, FIELD_LABEL_ANONYMIZE_MESSAGES,
+                    TOOLTIP_SETTINGS_MAKE_MESSAGES_ANONYMOUS);
+            IObservableValue swt = WidgetProperties.selection().observe(anonMessages);
+            IObservableValue emf = EMFProperties.value(USER_SETTINGS__ANONYMIZE_MESSAGES).observe(server);
+            context.bindValue(swt, emf);
+        }
+        return makeAnonymousGroup;
+    }
+
+    private static Link createLabelWithLink(Composite parent, String labelText, String linkText, String toolTip) {
+        createLabel(parent, labelText, toolTip);
+        
+        Link link = new Link(parent, SWT.NONE);
+        link.setText(linkText);
+        return link;
+    }
+    
+    private static Text createLabelWithText(Composite parent, String labelText, String textMessage, String toolTip) {
+        createLabel(parent, labelText, toolTip);
+        
+        Text text = new Text(parent, SWT.BORDER);
+        text.setMessage(textMessage);
+        calibrateTooltip(new DefaultToolTip(text), toolTip);
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(text);
+        return text;
+    }
+    
+    private static void createLabel(Composite parent, String labelText, String toolTip) {
+        Label label = new Label(parent, SWT.NONE);
+        label.setText(labelText);
+        calibrateTooltip(new DefaultToolTip(label), toolTip);
+    }
+    
+    private static Button createGroupCheckButton(Group group, String buttonText, String toolTipText) {
+        Button button = new Button(group, SWT.CHECK);
+        button.setText(buttonText);
+        calibrateTooltip(new DefaultToolTip(button), toolTipText);
+        return button;
+    }
+
+    private static void calibrateTooltip(DefaultToolTip toolTip, String toolTipText) {
+        toolTip.setText(toolTipText);
+        toolTip.setFont(JFaceResources.getDialogFont());
+        toolTip.setShift(TOOLTIP_DISPLACEMENT);
+        toolTip.setHideDelay(TOOLTIP_MS_HIDE_DELAY);
+    }
+    
+    @Override
+    protected void okPressed() {
+        server.setEnabled(true);
+        super.okPressed();
+    }
+
+    @Override
+    protected void cancelPressed() {
+        server.setEnabled(false);
+        super.cancelPressed();
+    }
+    
+    /**
+     * Tries to open an URL with an external web browser. If one is configure in the Eclipse preferences (General &gt; Web Browser) it will
+     * prefer that over the operating system's default browser. If either way to open an external browser does not succeed, this method will
+     * this will open a new editor to display the URL within the Eclipse IDE.
+     */
+    private static void openInExternalBrowser(String url) {
+        try {
+            IWebBrowser externalBrowser = PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser();
+            externalBrowser.openURL(new URL(url));
+        } catch (Throwable e) {
+            try {
+                if (!Program.launch(url)) {
+                    openInDefaultBrowser(url);
+                }
+            } catch (Throwable t) {
+                t.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Tries to open an URL wit the web browser configured in the Eclipse preferences (General &gt; Web Browser). By default, this will open
+     * a new editor to display the URL within the Eclipse IDE.
+     */
+    private static void openInDefaultBrowser(String url) {
+        try {
+            IWebBrowser defaultBrowser = PlatformUI.getWorkbench().getBrowserSupport().createBrowser(null);
+            defaultBrowser.openURL(new URL(url));
+        } catch (Throwable t) {
+            // Ignore failure; this method is best effort.
+            t.printStackTrace();
+        }
+    }
+
+}
diff --git a/bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineServerConnection.java b/bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineServerConnection.java
new file mode 100644 (file)
index 0000000..8548b7a
--- /dev/null
@@ -0,0 +1,290 @@
+package org.simantics.aeri.ui.redmine;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.epp.internal.logging.aeri.ide.IServerDescriptor;
+import org.eclipse.epp.logging.aeri.core.ILink;
+import org.eclipse.epp.logging.aeri.core.IModelFactory;
+import org.eclipse.epp.logging.aeri.core.IProblemState;
+import org.eclipse.epp.logging.aeri.core.IReport;
+import org.eclipse.epp.logging.aeri.core.IReportProcessor;
+import org.eclipse.epp.logging.aeri.core.ISendOptions;
+import org.eclipse.epp.logging.aeri.core.IServerConnection;
+import org.eclipse.epp.logging.aeri.core.IStackTraceElement;
+import org.eclipse.epp.logging.aeri.core.ISystemSettings;
+import org.eclipse.epp.logging.aeri.core.IThrowable;
+import org.eclipse.epp.logging.aeri.core.ProblemStatus;
+import org.eclipse.epp.logging.aeri.core.Severity;
+import org.eclipse.epp.logging.aeri.core.util.Links;
+import org.eclipse.epp.logging.aeri.core.util.Reports;
+import org.eclipse.epp.logging.aeri.core.util.Statuses;
+import org.simantics.aeri.redmine.core.settings.RedmineAERISettings;
+
+import com.google.common.util.concurrent.AbstractIdleService;
+import com.taskadapter.redmineapi.Params;
+import com.taskadapter.redmineapi.RedmineException;
+import com.taskadapter.redmineapi.RedmineManager;
+import com.taskadapter.redmineapi.RedmineManagerFactory;
+import com.taskadapter.redmineapi.bean.Issue;
+import com.taskadapter.redmineapi.bean.IssueFactory;
+import com.taskadapter.redmineapi.internal.ResultsWrapper;
+
+/**
+ * @author jsjani
+ *
+ */
+public class RedmineServerConnection extends AbstractIdleService implements IServerConnection {
+
+    private static final String LINE_SEPARATOR = System.lineSeparator();
+
+    private final IServerDescriptor server;
+    private final ISystemSettings systemSettings;
+    private final RedmineAERISettings redmineSettings;
+    private final File configurationArea;
+    private final ILink redmineUrl;
+    private final String projectId;
+
+    private RedmineManager redmine;
+
+    @Inject
+    public RedmineServerConnection(IServerDescriptor descriptor, RedmineAERISettings redmineSettings, ISystemSettings system, File configurationArea) {
+        this.systemSettings = Objects.requireNonNull(system);
+        this.redmineSettings = Objects.requireNonNull(redmineSettings);
+        this.configurationArea = Objects.requireNonNull(configurationArea);
+        this.server = Objects.requireNonNull(descriptor);
+        this.projectId = Objects.requireNonNull(getProjectIdParameter(descriptor));
+        
+        this.redmineUrl = Links.Link(descriptor, "org.simantics.aeri.ui.redmine.redmine.link");
+    }
+    
+    private static String getProjectIdParameter(IServerDescriptor server) {
+        IConfigurationElement element = server.getConfigurationElement();
+        IConfigurationElement[] children = element.getChildren("parameter"); //$NON-NLS-1$
+        for (IConfigurationElement child : children) {
+            if ("org.simantics.aeri.ui.redmine.redmine.project_id".equals(child.getAttribute("key"))) {
+                return child.getAttribute("value");
+            }
+        }
+        return null;
+    }
+    
+    @PostConstruct
+    private void e4Start() {
+        startAsync();
+    }
+
+    @Override
+    public IProblemState interested(IStatus status, IEclipseContext eventScopeContext, IProgressMonitor monitor) {
+        IProblemState res = IModelFactory.eINSTANCE.createProblemState();
+        
+        String fingerprint = Statuses.traceIdentityHash(status);
+        
+        Params params = new Params().add("project_id", projectId).add("f[]", "subject").add("op[subject]", "~").add("v[subject][]", fingerprint);
+        try {
+            ResultsWrapper<Issue> results = redmine.getIssueManager().getIssues(params);
+            List<Issue> issues = results.getResults();
+            if (issues.isEmpty()) {
+                res.setStatus(ProblemStatus.NEW);
+                res.setMessage("New issue found! Please send a report");
+            } else {
+                res.setStatus(ProblemStatus.CONFIRMED);
+                
+                StringBuilder sb = new StringBuilder();
+                sb.append("This issue has already been reported ").append(issues.size()).append(" times:").append(LINE_SEPARATOR).append(LINE_SEPARATOR);
+                
+                for (Issue issue : issues) {
+                    String bugurl = redmineUrl.getHref() + "/issues/" + issue.getId();
+                    sb.append("<a href=\"" + bugurl + "\">#" + issue.getId() + "</a>").append(LINE_SEPARATOR);
+                }
+                sb.append(LINE_SEPARATOR);
+                sb.append("Either edit an existing issue listed above or send a new report.");
+                res.setMessage(sb.toString());
+            }
+        } catch (RedmineException e) {
+            e.printStackTrace();
+            res.setStatus(ProblemStatus.FAILURE);
+            res.setMessage(e.getMessage());
+        }
+        return res;
+    }
+
+    /**
+     * 
+     * See <a href="http://www.redmine.org/projects/redmine/wiki/Rest_IssueStatuses">Redmine REST API</a>
+     * 
+     * @param issue
+     * @return
+     */
+    private static ProblemStatus resolveStatus(Issue issue) {
+        switch (issue.getStatusId()) {
+        case 1:
+        case 2:
+            return ProblemStatus.CONFIRMED;
+        case 3:
+        case 5:
+            return ProblemStatus.FIXED;
+        case 4:
+            return ProblemStatus.NEEDINFO;
+        case 6:
+            return ProblemStatus.WONTFIX;
+        case 8:
+            return ProblemStatus.NEEDINFO;
+        default:
+            return ProblemStatus.NEW;
+        }
+    }
+
+    @Override
+    public IReport transform(IStatus status, IEclipseContext context) {
+        ISendOptions options = context.get(ISendOptions.class);
+        IReport report = Reports.newReport(status);
+        report.setComment(options.getComment());
+        for (IReportProcessor processor : options.getEnabledProcessors()) {
+            processor.process(report, status, context);
+        }
+        report.setAnonymousId(options.getReporterId());
+        report.setName(options.getReporterName());
+        report.setEmail(options.getReporterEmail());
+        report.setSeverity(options.getSeverity());
+        return report;
+    }
+
+    @Override
+    public IProblemState submit(IStatus status, IEclipseContext context, IProgressMonitor monitor) throws IOException {
+        IReport report = transform(status, context);
+        String fingerprint = Statuses.traceIdentityHash(status);
+        IProblemState response = upload(report, monitor, fingerprint);
+
+        String message = response.getMessage();
+        response.setMessage(message);
+        return response;
+    }
+    
+    private static void appendStackTrace(IThrowable throwable, StringBuilder builder) {
+        builder.append(String.format("%s: %s", throwable.getClassName(), throwable.getMessage())).append(LINE_SEPARATOR);
+        for (IStackTraceElement element : throwable.getStackTrace()) {
+            builder.append(String.format("\t at %s.%s(%s:%s)", element.getClassName(), element.getMethodName(),
+                    element.getFileName(), element.getLineNumber())).append(LINE_SEPARATOR);
+        }
+        IThrowable cause = throwable.getCause();
+        if (cause != null) {
+            builder.append("Caused by: ");
+            appendStackTrace(cause, builder);
+        }
+    }
+
+    private IProblemState upload(IReport report, IProgressMonitor monitor, String fingerprint) {
+        IProblemState result = IModelFactory.eINSTANCE.createProblemState();
+        org.eclipse.epp.logging.aeri.core.IStatus status = report.getStatus();
+        String issueName = status.getMessage();
+        String description = generateReportMessage(report);
+        
+        try {
+            Issue newIssue = IssueFactory.create(27, issueName + " [AERI=" + fingerprint+"]");
+            newIssue.setDescription(description);
+            newIssue.setPriorityId(resolvePriority(report));
+            
+            Issue createdIssue = redmine.getIssueManager().createIssue(newIssue);
+            Integer id = createdIssue.getId();
+            Links.addLink(result, Links.REL_SUBMISSION, redmineUrl.getHref() + "/issues/" + id, "Submission URL: ");
+            
+            String message = "View reported issue: <a href=\"" + result.getLinks().iterator().next().getValue().getHref() + "\">#" + id + "</a>"; 
+            result.setMessage(message);
+        } catch (RedmineException e) {
+            e.printStackTrace();
+            result.setStatus(ProblemStatus.FAILURE);
+            result.setMessage(e.getMessage());
+        }
+        return result;
+    }
+    
+    private String generateReportMessage(IReport report) {
+        String comment = report.getComment();
+        org.eclipse.epp.logging.aeri.core.IStatus status = report.getStatus();
+        
+        StringBuilder sb = new StringBuilder();
+        if (comment != null)
+            sb.append(comment).append("\n");
+        
+        sb.append(LINE_SEPARATOR);
+        sb.append("h2. Product Information").append(LINE_SEPARATOR);
+        
+        sb.append("\n<pre>\n");
+        appendProductInformation(report, sb);
+        sb.append("</pre>\n");
+        
+        sb.append("h2. Exception stack trace").append(LINE_SEPARATOR);
+        sb.append("\n<pre>\n");
+        appendStackTrace(status.getException(), sb);
+        sb.append("</pre>\n");
+        
+        return sb.toString();
+    }
+
+    
+    /**
+     *  eclipseBuildId      some-id
+        eclipseProduct      org.simantics.desktop.product.desktopProduct
+        javaRuntimeVersion  1.8.0_111-b14
+        osgiWs              win32
+        osgiOs              win32
+        osgiOsVersion       6.1.0
+        osgiArch            x86_64
+     */
+    private void appendProductInformation(IReport report, StringBuilder sb) {
+        sb.append(LINE_SEPARATOR);
+        sb.append("eclipseProduct     ").append(report.getEclipseProduct()).append(LINE_SEPARATOR);
+        sb.append("eclipseBuildId     ").append(report.getEclipseBuildId()).append(LINE_SEPARATOR);
+        sb.append("javaRuntimeVersion ").append(report.getJavaRuntimeVersion()).append(LINE_SEPARATOR);
+        sb.append("osgiWs             ").append(report.getOsgiWs()).append(LINE_SEPARATOR);
+        sb.append("osgiOs             ").append(report.getOsgiOs()).append(LINE_SEPARATOR);
+        sb.append("osgiOsVersion      ").append(report.getOsgiOsVersion()).append(LINE_SEPARATOR);
+        sb.append("osgiArch           ").append(report.getOsgiArch()).append(LINE_SEPARATOR);
+        sb.append(LINE_SEPARATOR);
+    }
+
+    /**
+     * See <a href="http://www.redmine.org/projects/redmine/wiki/Rest_Enumerations">Redmine REST API</a>
+     * 
+     * @param report
+     * @return
+     */
+    private Integer resolvePriority(IReport report) {
+        Severity severity = report.getSeverity();
+        switch (severity.getValue()) {
+        case Severity.CRITICAL_VALUE:
+            return 7;
+        case Severity.MAJOR_VALUE:
+            return 5;
+        case Severity.MINOR_VALUE:
+            return 13;
+        default:
+            return 4;
+        }
+    }
+
+    @Override
+    public void discarded(IStatus status, IEclipseContext eventScopeContext) {
+        // do nothing
+    }
+
+    @Override
+    protected void startUp() throws Exception {
+        this.redmine = RedmineManagerFactory.createWithApiKey(redmineUrl.getHref(), redmineSettings.getApiKey());
+    }
+
+    @Override
+    protected void shutDown() throws Exception {
+    }
+
+}
index 892730d370c9364a37d21186d05abbd87110bf31..20d189dbe648d7cfc80035ae4e69ed445a9bbf12 100644 (file)
@@ -58,6 +58,7 @@ org.eclipse.e4.ui.css.theme.e4_classic
 
    <features>
       <feature id="org.simantics.desktop.product" version="1.0.0.qualifier"/>
+      <feature id="org.simantics.aeri.feature" version="1.0.0.qualifier"/>
    </features>
 
 
diff --git a/features/org.simantics.aeri.ui.feature/.project b/features/org.simantics.aeri.ui.feature/.project
new file mode 100644 (file)
index 0000000..7d6a148
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.aeri.ui.feature</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.FeatureBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.FeatureNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/features/org.simantics.aeri.ui.feature/build.properties b/features/org.simantics.aeri.ui.feature/build.properties
new file mode 100644 (file)
index 0000000..82ab19c
--- /dev/null
@@ -0,0 +1 @@
+bin.includes = feature.xml\r
diff --git a/features/org.simantics.aeri.ui.feature/feature.xml b/features/org.simantics.aeri.ui.feature/feature.xml
new file mode 100644 (file)
index 0000000..2fa773b
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.simantics.aeri.feature"
+      label="Simantics AERI Feature"
+      version="1.0.0.qualifier">
+
+   <description url="http://www.example.com/description">
+      [Enter Feature Description here.]
+   </description>
+
+   <copyright url="http://www.example.com/copyright">
+      [Enter Copyright Description here.]
+   </copyright>
+
+   <license url="http://www.example.com/license">
+      [Enter License Description here.]
+   </license>
+
+   <includes
+         id="org.eclipse.epp.logging.aeri.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.mylyn.commons.notifications"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.mylyn.commons"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.epp.logging.3rd.feature"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.apache.commons.lang3"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.hamcrest.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.simantics.aeri.ui.redmine.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.simantics.aeri.ui.redmine"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
index d09693543cf82dbc5f5920be44282e138f8253ce..d1d24d9cc52d52e1bf191eeb4e15723f28839581 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?pde version="3.8"?><target name="Eclipse Mars.2" sequenceNumber="223">
+<?pde version="3.8"?><target name="Eclipse Mars.2" sequenceNumber="240">
 <locations>
 <location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
 <unit id="org.objectweb.asm.xml.source" version="5.0.1.v201404251740"/>
@@ -21,6 +21,8 @@
 <location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
 <unit id="org.eclipse.mylyn.wikitext_feature.feature.group" version="2.7.0.v20151015-1452"/>
 <unit id="org.eclipse.emf.sdk.feature.group" version="2.11.2.v20160208-0841"/>
+<unit id="org.eclipse.mylyn.commons.notifications.feature.group" version="1.10.0.v20151102-1814"/>
+<unit id="org.eclipse.mylyn.commons.feature.group" version="3.18.0.v20151116-1930"/>
 <unit id="org.eclipse.epp.mpc.feature.group" version="1.4.2.v20160210-2005"/>
 <repository location="http://www.simantics.org/update/mars"/>
 </location>
 <unit id="org.apache.batik" version="1.8.0.201611220734"/>
 <repository location="http://www.simantics.org/download/master/external-components/manual"/>
 </location>
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.epp.logging.aeri.feature.source.feature.group" version="2.0.3.v20160923-1310"/>
+<unit id="org.eclipse.epp.logging.3rd.feature.feature.group" version="2.0.3.v20160905-1029"/>
+<unit id="org.eclipse.epp.logging.3rd.feature.source.feature.group" version="2.0.3.v20160905-1029"/>
+<unit id="org.eclipse.epp.logging.aeri.feature.feature.group" version="2.0.3.v20160923-1310"/>
+<repository location="http://download.eclipse.org/technology/epp/logging/stable/"/>
+</location>
 </locations>
 </target>