From: jsimomaa Date: Wed, 4 Jan 2017 11:10:17 +0000 (+0200) Subject: Experiment around with AERI in Simantics Products X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=refs%2Fheads%2Fprivate%2Fjsimomaa-aeri;p=simantics%2Fplatform.git Experiment around with AERI in Simantics Products refs #6935 Change-Id: Idcd617129e21d6836865cd2ab40bbd3dc074db59 --- diff --git a/bundles/org.simantics.aeri.ui.redmine.core/.classpath b/bundles/org.simantics.aeri.ui.redmine.core/.classpath new file mode 100644 index 000000000..b862a296d --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.aeri.ui.redmine.core/.gitignore b/bundles/org.simantics.aeri.ui.redmine.core/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/.gitignore @@ -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 index 000000000..67ba378cb --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/.project @@ -0,0 +1,28 @@ + + + org.simantics.aeri.ui.redmine.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + 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 index 000000000..295926d96 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 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 index 000000000..2bac6bc40 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/META-INF/MANIFEST.MF @@ -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 index 000000000..4d3b18277 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/build.properties @@ -0,0 +1,10 @@ +# + +bin.includes = .,\ + model/,\ + META-INF/,\ + plugin.xml,\ + plugin.properties +jars.compile.order = . +source.. = src/ +output.. = bin/ 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 index 000000000..f3f97cdd3 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.ecore @@ -0,0 +1,8 @@ + + + + + + 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 index 000000000..f6bc66375 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/model/RedmineAERISettings.genmodel @@ -0,0 +1,14 @@ + + + RedmineAERISettings.ecore + + + + + + 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 index 000000000..037e1d123 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/plugin.properties @@ -0,0 +1,4 @@ +# + +pluginName = RedmineAERISettings Model +providerName = www.example.org 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 index 000000000..45262784d --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/plugin.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + 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 index 000000000..a1cd85f52 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/di/RedmineAERISettingsCreationFunction.java @@ -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()); + + // 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 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) 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 convert(String string) { + return Splitter.on(';').omitEmptyStrings().trimResults().splitToList(string); + + } + + static String convert(List 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 index 000000000..705c02da0 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/internal/Activator.java @@ -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 index 000000000..98e5aaf3e --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettings.java @@ -0,0 +1,50 @@ +/** + */ +package org.simantics.aeri.redmine.core.settings; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'Redmine AERI Settings'. + * + * + *

+ * The following features are supported: + *

+ *
    + *
  • {@link org.simantics.aeri.redmine.core.settings.RedmineAERISettings#getApiKey Api Key}
  • + *
+ * + * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage#getRedmineAERISettings() + * @model + * @generated + */ +public interface RedmineAERISettings extends EObject { + /** + * Returns the value of the 'Api Key' attribute. + * + *

+ * If the meaning of the 'Api Key' attribute isn't clear, + * there really should be more of a description here... + *

+ * + * @return the value of the 'Api Key' 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 Api Key}' attribute. + * + * + * @param value the new value of the 'Api Key' 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 index 000000000..6204837ea --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsFactory.java @@ -0,0 +1,42 @@ +/** + */ +package org.simantics.aeri.redmine.core.settings; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage + * @generated + */ +public interface RedmineAERISettingsFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + RedmineAERISettingsFactory eINSTANCE = org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsFactoryImpl.init(); + + /** + * Returns a new object of class 'Redmine AERI Settings'. + * + * + * @return a new object of class 'Redmine AERI Settings'. + * @generated + */ + RedmineAERISettings createRedmineAERISettings(); + + /** + * Returns the package supported by this factory. + * + * + * @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 index 000000000..07d84ae99 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/RedmineAERISettingsPackage.java @@ -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; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
    + *
  • each class,
  • + *
  • each feature of each class,
  • + *
  • each operation of each class,
  • + *
  • each enum,
  • + *
  • and each data type
  • + *
+ * + * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsFactory + * @model kind="package" + * @generated + */ +public interface RedmineAERISettingsPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "settings"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http://www.simantics.org/emf/redmine-aeri-settings"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "RedmineAERISettings"; + + /** + * The singleton instance of the package. + * + * + * @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 Redmine AERI Settings}' class. + * + * + * @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 'Api Key' attribute. + * + * + * @generated + * @ordered + */ + int REDMINE_AERI_SETTINGS__API_KEY = 0; + + /** + * The number of structural features of the 'Redmine AERI Settings' class. + * + * + * @generated + * @ordered + */ + int REDMINE_AERI_SETTINGS_FEATURE_COUNT = 1; + + /** + * The number of operations of the 'Redmine AERI Settings' class. + * + * + * @generated + * @ordered + */ + int REDMINE_AERI_SETTINGS_OPERATION_COUNT = 0; + + + /** + * Returns the meta object for class '{@link org.simantics.aeri.redmine.core.settings.RedmineAERISettings Redmine AERI Settings}'. + * + * + * @return the meta object for class 'Redmine AERI Settings'. + * @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 Api Key}'. + * + * + * @return the meta object for the attribute 'Api Key'. + * @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. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + RedmineAERISettingsFactory getRedmineAERISettingsFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
    + *
  • each class,
  • + *
  • each feature of each class,
  • + *
  • each operation of each class,
  • + *
  • each enum,
  • + *
  • and each data type
  • + *
+ * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsImpl Redmine AERI Settings}' class. + * + * + * @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 'Api Key' attribute feature. + * + * + * @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 index 000000000..9dcdc836c --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsFactoryImpl.java @@ -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.*; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class RedmineAERISettingsFactoryImpl extends EFactoryImpl implements RedmineAERISettingsFactory { + /** + * Creates the default factory implementation. + * + * + * @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. + * + * + * @generated + */ + public RedmineAERISettingsFactoryImpl() { + super(); + } + + /** + * + * + * @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"); + } + } + + /** + * + * + * @generated + */ + public RedmineAERISettings createRedmineAERISettings() { + RedmineAERISettingsImpl redmineAERISettings = new RedmineAERISettingsImpl(); + return redmineAERISettings; + } + + /** + * + * + * @generated + */ + public RedmineAERISettingsPackage getRedmineAERISettingsPackage() { + return (RedmineAERISettingsPackage)getEPackage(); + } + + /** + * + * + * @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 index 000000000..e2990c1ab --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsImpl.java @@ -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; + +/** + * + * An implementation of the model object 'Redmine AERI Settings'. + * + *

+ * The following features are implemented: + *

+ *
    + *
  • {@link org.simantics.aeri.redmine.core.settings.impl.RedmineAERISettingsImpl#getApiKey Api Key}
  • + *
+ * + * @generated + */ +public class RedmineAERISettingsImpl extends MinimalEObjectImpl.Container implements RedmineAERISettings { + /** + * The default value of the '{@link #getApiKey() Api Key}' attribute. + * + * + * @see #getApiKey() + * @generated + * @ordered + */ + protected static final String API_KEY_EDEFAULT = null; + + /** + * The cached value of the '{@link #getApiKey() Api Key}' attribute. + * + * + * @see #getApiKey() + * @generated + * @ordered + */ + protected String apiKey = API_KEY_EDEFAULT; + + /** + * + * + * @generated + */ + protected RedmineAERISettingsImpl() { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() { + return RedmineAERISettingsPackage.Literals.REDMINE_AERI_SETTINGS; + } + + /** + * + * + * @generated + */ + public String getApiKey() { + return apiKey; + } + + /** + * + * + * @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)); + } + + /** + * + * + * @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); + } + + /** + * + * + * @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); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case RedmineAERISettingsPackage.REDMINE_AERI_SETTINGS__API_KEY: + setApiKey(API_KEY_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @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); + } + + /** + * + * + * @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 index 000000000..d9bf6453c --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/impl/RedmineAERISettingsPackageImpl.java @@ -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; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class RedmineAERISettingsPackageImpl extends EPackageImpl implements RedmineAERISettingsPackage { + /** + * + * + * @generated + */ + private EClass redmineAERISettingsEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

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. + * + * + * @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); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this model, and for any others upon which it depends. + * + *

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. + * + * + * @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; + } + + /** + * + * + * @generated + */ + public EClass getRedmineAERISettings() { + return redmineAERISettingsEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getRedmineAERISettings_ApiKey() { + return (EAttribute)redmineAERISettingsEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public RedmineAERISettingsFactory getRedmineAERISettingsFactory() { + return (RedmineAERISettingsFactory)getEFactoryInstance(); + } + + /** + * + * + * @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. + * + * + * @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); + } + + /** + * + * + * @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. + * + * + * @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 index 000000000..3415cbf87 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsAdapterFactory.java @@ -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.*; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage + * @generated + */ +public class RedmineAERISettingsAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static RedmineAERISettingsPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public RedmineAERISettingsAdapterFactory() { + if (modelPackage == null) { + modelPackage = RedmineAERISettingsPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @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 createXXX methods. + * + * + * @generated + */ + protected RedmineAERISettingsSwitch modelSwitch = + new RedmineAERISettingsSwitch() { + @Override + public Adapter caseRedmineAERISettings(RedmineAERISettings object) { + return createRedmineAERISettingsAdapter(); + } + @Override + public Adapter defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @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 Redmine AERI Settings}'. + * + * 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. + * + * @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. + * + * This default implementation returns null. + * + * @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 index 000000000..86813b34f --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine.core/src/org/simantics/aeri/redmine/core/settings/util/RedmineAERISettingsSwitch.java @@ -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.*; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX 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. + * + * @see org.simantics.aeri.redmine.core.settings.RedmineAERISettingsPackage + * @generated + */ +public class RedmineAERISettingsSwitch extends Switch { + /** + * The cached model package + * + * + * @generated + */ + protected static RedmineAERISettingsPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public RedmineAERISettingsSwitch() { + if (modelPackage == null) { + modelPackage = RedmineAERISettingsPackage.eINSTANCE; + } + } + + /** + * Checks whether this is a switch for the given package. + * + * + * @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 caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX 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 'Redmine AERI Settings'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Redmine AERI Settings'. + * @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 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'EObject'. + * @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 index 000000000..b0c7e37d9 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bundles/org.simantics.aeri.ui.redmine/.gitignore b/bundles/org.simantics.aeri.ui.redmine/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/.gitignore @@ -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 index 000000000..e04ac9844 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/.project @@ -0,0 +1,28 @@ + + + org.simantics.aeri.ui.redmine + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + 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 index 000000000..295926d96 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 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 index 000000000..458a7e910 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/META-INF/MANIFEST.MF @@ -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 index 000000000..63a34a80f --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/build.properties @@ -0,0 +1,7 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + lib/redmine-java-api-3.0.0.jar,\ + lib/json-20090211.jar +source.. = src/ 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 index 000000000..8a5b3c402 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 index 000000000..1dbf7885e 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 index 000000000..ef2909409 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 index 000000000..7b565a3c4 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 index 000000000..dbd7e133f 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 index 000000000..eacf43ad4 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/plugin.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + 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 index 000000000..7e84bc999 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineCredentialsDialog.java @@ -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 org.eclipse.epp.internal.logging.aeri.ide.dialogs.ConfigureServerDialog + * + */ +public class RedmineCredentialsDialog extends TitleAreaDialog { + + private static final EAttribute REDMINE_SETTINGS__API_KEY = RedmineAERISettingsPackage.eINSTANCE.getRedmineAERISettings_ApiKey(); + + private static Map SYSTEM_SETTINGS_TO_SERVER = systemSettingsToServer(); + + private static Map systemSettingsToServer() { + Map 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 {0} 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 {0} 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 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, "" + redmineEndpoint.getHref() + "", 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 > 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 > 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 index 000000000..8548b7a34 --- /dev/null +++ b/bundles/org.simantics.aeri.ui.redmine/src/org/simantics/aeri/ui/redmine/RedmineServerConnection.java @@ -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 results = redmine.getIssueManager().getIssues(params); + List 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("#" + issue.getId() + "").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 Redmine REST API + * + * @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: #" + id + ""; + 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

\n");
+        appendProductInformation(report, sb);
+        sb.append("
\n"); + + sb.append("h2. Exception stack trace").append(LINE_SEPARATOR); + sb.append("\n
\n");
+        appendStackTrace(status.getException(), sb);
+        sb.append("
\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 Redmine REST API + * + * @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 { + } + +} diff --git a/bundles/org.simantics.desktop.product/simantics-desktop.product b/bundles/org.simantics.desktop.product/simantics-desktop.product index 892730d37..20d189dbe 100644 --- a/bundles/org.simantics.desktop.product/simantics-desktop.product +++ b/bundles/org.simantics.desktop.product/simantics-desktop.product @@ -58,6 +58,7 @@ org.eclipse.e4.ui.css.theme.e4_classic + diff --git a/features/org.simantics.aeri.ui.feature/.project b/features/org.simantics.aeri.ui.feature/.project new file mode 100644 index 000000000..7d6a1486a --- /dev/null +++ b/features/org.simantics.aeri.ui.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.aeri.ui.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.simantics.aeri.ui.feature/build.properties b/features/org.simantics.aeri.ui.feature/build.properties new file mode 100644 index 000000000..82ab19c62 --- /dev/null +++ b/features/org.simantics.aeri.ui.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.simantics.aeri.ui.feature/feature.xml b/features/org.simantics.aeri.ui.feature/feature.xml new file mode 100644 index 000000000..2fa773bd3 --- /dev/null +++ b/features/org.simantics.aeri.ui.feature/feature.xml @@ -0,0 +1,63 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + + + diff --git a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target index d09693543..d1d24d9cc 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target +++ b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target @@ -1,5 +1,5 @@ - + @@ -21,6 +21,8 @@ + + @@ -217,5 +219,12 @@ + + + + + + +