Bug 565945: improve character sheet
Change-Id: I7c5c56df5fb9272d939105f09d995bc759577709
diff --git a/plugins/org.eclipse.skills/model/Skills.ecore b/plugins/org.eclipse.skills/model/Skills.ecore
index 4f54954..9fe373d 100644
--- a/plugins/org.eclipse.skills/model/Skills.ecore
+++ b/plugins/org.eclipse.skills/model/Skills.ecore
@@ -36,6 +36,7 @@
</eOperations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Badge">
+ <eOperations name="getImageDescriptor" eType="#//ImageDescriptor"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="imageURL" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
@@ -50,7 +51,7 @@
<eOperations name="consume">
<eParameters name="reward" eType="#//Reward"/>
</eOperations>
- <eOperations name="getAvatar" eType="#//ImageData"/>
+ <eOperations name="getAvatar" eType="#//ImageDescriptor"/>
<eOperations name="getSkill" eType="#//Skill">
<eParameters name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eOperations>
@@ -166,7 +167,8 @@
<eLiterals name="EXPERT" value="2" literal="Expert"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EDataType" name="CustomDependencyDefinition" instanceClassName="org.eclipse.skills.dependencies.CustomDependencyDefinition"/>
- <eClassifiers xsi:type="ecore:EDataType" name="ImageData" instanceClassName="org.eclipse.swt.graphics.ImageData"/>
+ <eClassifiers xsi:type="ecore:EDataType" name="ImageDescriptor" instanceClassName="org.eclipse.jface.resource.ImageDescriptor"
+ serializable="false"/>
<eClassifiers xsi:type="ecore:EDataType" name="ISkillService" instanceClassName="org.eclipse.skills.service.ISkillService"/>
<eClassifiers xsi:type="ecore:EClass" name="UserDependency" abstract="true" eSuperTypes="#//Dependency">
<eStructuralFeatures xsi:type="ecore:EReference" name="user" ordered="false" unique="false"
diff --git a/plugins/org.eclipse.skills/model/Skills.genmodel b/plugins/org.eclipse.skills/model/Skills.genmodel
index 9ef7eb3..27be37f 100644
--- a/plugins/org.eclipse.skills/model/Skills.genmodel
+++ b/plugins/org.eclipse.skills/model/Skills.genmodel
@@ -17,7 +17,7 @@
</genEnums>
<genDataTypes ecoreDataType="Skills.ecore#//Date"/>
<genDataTypes ecoreDataType="Skills.ecore#//CustomDependencyDefinition"/>
- <genDataTypes ecoreDataType="Skills.ecore#//ImageData"/>
+ <genDataTypes ecoreDataType="Skills.ecore#//ImageDescriptor"/>
<genDataTypes ecoreDataType="Skills.ecore#//ISkillService"/>
<genClasses ecoreClass="Skills.ecore#//Task">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Skills.ecore#//Task/description"/>
@@ -46,6 +46,7 @@
<genClasses ecoreClass="Skills.ecore#//Badge">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute Skills.ecore#//Badge/title"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute Skills.ecore#//Badge/imageURL"/>
+ <genOperations ecoreOperation="Skills.ecore#//Badge/getImageDescriptor"/>
</genClasses>
<genClasses ecoreClass="Skills.ecore#//User">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute Skills.ecore#//User/name"/>
diff --git a/plugins/org.eclipse.skills/model/model.aird b/plugins/org.eclipse.skills/model/model.aird
index 1a5102a..d98cfc8 100644
--- a/plugins/org.eclipse.skills/model/model.aird
+++ b/plugins/org.eclipse.skills/model/model.aird
@@ -5,7 +5,7 @@
<semanticResources>http://eclipse.org/skills/1.0.0</semanticResources>
<ownedViews xmi:type="viewpoint:DView" uid="_m68ZsEwrEeqwHIzbUoB2lQ">
<viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']"/>
- <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_n6l40EwrEeqwHIzbUoB2lQ" name="Skills Model" repPath="#_n4mUwEwrEeqwHIzbUoB2lQ" changeId="89e01c84-0727-4aef-a702-f77eb25b5843">
+ <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_n6l40EwrEeqwHIzbUoB2lQ" name="Skills Model" repPath="#_n4mUwEwrEeqwHIzbUoB2lQ" changeId="4a45e48a-3991-46f2-b065-bb6f40324f4b">
<description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/>
<target xmi:type="ecore:EPackage" href="Skills.ecore#/"/>
</ownedRepresentationDescriptors>
@@ -143,6 +143,10 @@
<styles xmi:type="notation:FontStyle" xmi:id="_rImrRNrpEeq_CZJuNlb8eA" fontName="Cantarell" fontHeight="8"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_rImrRdrpEeq_CZJuNlb8eA"/>
</children>
+ <children xmi:type="notation:Node" xmi:id="_Nd9l0BRZEeu0cKJLM565Cg" type="3010" element="_NdivEBRZEeu0cKJLM565Cg">
+ <styles xmi:type="notation:FontStyle" xmi:id="_Nd9l0RRZEeu0cKJLM565Cg" fontName="Cantarell" fontHeight="8"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Nd9l0hRZEeu0cKJLM565Cg"/>
+ </children>
<styles xmi:type="notation:SortingStyle" xmi:id="_rIbsKdrpEeq_CZJuNlb8eA"/>
<styles xmi:type="notation:FilteringStyle" xmi:id="_rIbsKtrpEeq_CZJuNlb8eA"/>
</children>
@@ -1338,6 +1342,14 @@
</ownedStyle>
<actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
</ownedElements>
+ <ownedElements xmi:type="diagram:DNodeListElement" uid="_NdivEBRZEeu0cKJLM565Cg" name="getImageDescriptor() : ImageDescriptor" tooltipText="getImageDescriptor() : ImageDescriptor">
+ <target xmi:type="ecore:EOperation" href="Skills.ecore#//Badge/getImageDescriptor"/>
+ <semanticElements xmi:type="ecore:EOperation" href="Skills.ecore#//Badge/getImageDescriptor"/>
+ <ownedStyle xmi:type="diagram:BundledImage" uid="_Ndj9MBRZEeu0cKJLM565Cg" labelAlignment="LEFT">
+ <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='Operation']/@style"/>
+ </ownedStyle>
+ <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='Operation']"/>
+ </ownedElements>
</ownedDiagramElements>
<ownedDiagramElements xmi:type="diagram:DNodeList" uid="_rGnHMdrpEeq_CZJuNlb8eA" name="Date" tooltipText="" width="14" height="5">
<target xmi:type="ecore:EDataType" href="Skills.ecore#//Date"/>
@@ -1415,7 +1427,7 @@
</ownedStyle>
<actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='Operation']"/>
</ownedElements>
- <ownedElements xmi:type="diagram:DNodeListElement" uid="_0rCe8OYaEeqiRLW56LILnw" name="getAvatar() : ImageData" tooltipText="getAvatar() : ImageData">
+ <ownedElements xmi:type="diagram:DNodeListElement" uid="_0rCe8OYaEeqiRLW56LILnw" name="getAvatar() : ImageDescriptor" tooltipText="getAvatar() : ImageDescriptor">
<target xmi:type="ecore:EOperation" href="Skills.ecore#//User/getAvatar"/>
<semanticElements xmi:type="ecore:EOperation" href="Skills.ecore#//User/getAvatar"/>
<ownedStyle xmi:type="diagram:BundledImage" uid="_0rDGAOYaEeqiRLW56LILnw" labelAlignment="LEFT">
@@ -2316,9 +2328,9 @@
<actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EDataType']/@subNodeMappings[name='EC_DataType_InstanceClassName']"/>
</ownedElements>
</ownedDiagramElements>
- <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_O5dToOYbEeqiRLW56LILnw" name="ImageData" tooltipText="" width="14" height="5">
- <target xmi:type="ecore:EDataType" href="Skills.ecore#//ImageData"/>
- <semanticElements xmi:type="ecore:EDataType" href="Skills.ecore#//ImageData"/>
+ <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_O5dToOYbEeqiRLW56LILnw" name="ImageDescriptor" tooltipText="" width="14" height="5">
+ <target xmi:type="ecore:EDataType" href="Skills.ecore#//ImageDescriptor"/>
+ <semanticElements xmi:type="ecore:EDataType" href="Skills.ecore#//ImageDescriptor"/>
<arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
<arrangeConstraints>KEEP_SIZE</arrangeConstraints>
<arrangeConstraints>KEEP_RATIO</arrangeConstraints>
@@ -2326,9 +2338,9 @@
<description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EDataType']/@style"/>
</ownedStyle>
<actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EDataType']"/>
- <ownedElements xmi:type="diagram:DNodeListElement" uid="_O5vngeYbEeqiRLW56LILnw" name="org.eclipse.swt.graphics.ImageData" tooltipText="">
- <target xmi:type="ecore:EDataType" href="Skills.ecore#//ImageData"/>
- <semanticElements xmi:type="ecore:EDataType" href="Skills.ecore#//ImageData"/>
+ <ownedElements xmi:type="diagram:DNodeListElement" uid="_O5vngeYbEeqiRLW56LILnw" name="org.eclipse.jface.resource.ImageDescriptor" tooltipText="">
+ <target xmi:type="ecore:EDataType" href="Skills.ecore#//ImageDescriptor"/>
+ <semanticElements xmi:type="ecore:EDataType" href="Skills.ecore#//ImageDescriptor"/>
<decorations xmi:type="viewpoint:Decoration" uid="_O5vnguYbEeqiRLW56LILnw">
<description xmi:type="description:SemanticBasedDecoration" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@decorationDescriptionsSet/@decorationDescriptions[name='External']"/>
</decorations>
diff --git a/plugins/org.eclipse.skills/plugin.xml b/plugins/org.eclipse.skills/plugin.xml
index 8abfc0c..e23d36a 100644
--- a/plugins/org.eclipse.skills/plugin.xml
+++ b/plugins/org.eclipse.skills/plugin.xml
@@ -38,7 +38,7 @@
</category>
<view
category="org.eclipse.skills.category"
- class="org.eclipse.skills.ui.views.character.CharacterSheet"
+ class="org.eclipse.skills.ui.views.character.CharacterView"
id="org.eclipse.skills.view.characterSheet"
name="Character Sheet"
restorable="true">
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IBadge.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IBadge.java
index c9e2680..5252a25 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IBadge.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IBadge.java
@@ -2,9 +2,8 @@
*/
package org.eclipse.skills.model;
-import java.io.IOException;
-
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.resource.ImageDescriptor;
/**
* <!-- begin-user-doc --> A representation of the model object '<em><b>Badge</b></em>'. <!-- end-user-doc -->
@@ -63,10 +62,11 @@
void setImageURL(String value);
/**
- * @throws IOException
- * on read errors
- * @generated NOT
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @model kind="operation" dataType="org.eclipse.skills.model.ImageDescriptor"
+ * @generated
*/
- byte[] getImageData() throws IOException;
+ ImageDescriptor getImageDescriptor();
} // IBadge
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/ISkillsPackage.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/ISkillsPackage.java
index 55e0c29..27aadec 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/ISkillsPackage.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/ISkillsPackage.java
@@ -307,13 +307,22 @@
int BADGE_FEATURE_COUNT = 2;
/**
+ * The operation id for the '<em>Get Image Descriptor</em>' operation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int BADGE___GET_IMAGE_DESCRIPTOR = 0;
+
+ /**
* The number of operations of the '<em>Badge</em>' class.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
* @ordered
*/
- int BADGE_OPERATION_COUNT = 0;
+ int BADGE_OPERATION_COUNT = 1;
/**
* The meta object id for the '{@link org.eclipse.skills.model.impl.MUser <em>User</em>}' class.
@@ -2000,15 +2009,14 @@
/**
- * The meta object id for the '<em>Image Data</em>' data type.
+ * The meta object id for the '<em>Image Descriptor</em>' data type.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
- * @see org.eclipse.swt.graphics.ImageData
- * @see org.eclipse.skills.model.impl.MSkillsPackage#getImageData()
+ * @see org.eclipse.jface.resource.ImageDescriptor
+ * @see org.eclipse.skills.model.impl.MSkillsPackage#getImageDescriptor()
* @generated
*/
- int IMAGE_DATA = 30;
-
+ int IMAGE_DESCRIPTOR = 30;
/**
* The meta object id for the '<em>ISkill Service</em>' data type.
@@ -2235,6 +2243,16 @@
EAttribute getBadge_ImageURL();
/**
+ * Returns the meta object for the '{@link org.eclipse.skills.model.IBadge#getImageDescriptor() <em>Get Image Descriptor</em>}' operation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the '<em>Get Image Descriptor</em>' operation.
+ * @see org.eclipse.skills.model.IBadge#getImageDescriptor()
+ * @generated
+ */
+ EOperation getBadge__GetImageDescriptor();
+
+ /**
* Returns the meta object for class '{@link org.eclipse.skills.model.IUser <em>User</em>}'.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -3096,15 +3114,15 @@
EDataType getCustomDependencyDefinition();
/**
- * Returns the meta object for data type '{@link org.eclipse.swt.graphics.ImageData <em>Image Data</em>}'.
+ * Returns the meta object for data type '{@link org.eclipse.jface.resource.ImageDescriptor <em>Image Descriptor</em>}'.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
- * @return the meta object for data type '<em>Image Data</em>'.
- * @see org.eclipse.swt.graphics.ImageData
- * @model instanceClass="org.eclipse.swt.graphics.ImageData"
+ * @return the meta object for data type '<em>Image Descriptor</em>'.
+ * @see org.eclipse.jface.resource.ImageDescriptor
+ * @model instanceClass="org.eclipse.jface.resource.ImageDescriptor" serializeable="false"
* @generated
*/
- EDataType getImageData();
+ EDataType getImageDescriptor();
/**
* Returns the meta object for data type '{@link org.eclipse.skills.service.ISkillService <em>ISkill Service</em>}'.
@@ -3309,6 +3327,14 @@
EAttribute BADGE__IMAGE_URL = eINSTANCE.getBadge_ImageURL();
/**
+ * The meta object literal for the '<em><b>Get Image Descriptor</b></em>' operation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EOperation BADGE___GET_IMAGE_DESCRIPTOR = eINSTANCE.getBadge__GetImageDescriptor();
+
+ /**
* The meta object literal for the '{@link org.eclipse.skills.model.impl.MUser <em>User</em>}' class.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -4017,14 +4043,14 @@
EDataType CUSTOM_DEPENDENCY_DEFINITION = eINSTANCE.getCustomDependencyDefinition();
/**
- * The meta object literal for the '<em>Image Data</em>' data type.
+ * The meta object literal for the '<em>Image Descriptor</em>' data type.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
- * @see org.eclipse.swt.graphics.ImageData
- * @see org.eclipse.skills.model.impl.MSkillsPackage#getImageData()
+ * @see org.eclipse.jface.resource.ImageDescriptor
+ * @see org.eclipse.skills.model.impl.MSkillsPackage#getImageDescriptor()
* @generated
*/
- EDataType IMAGE_DATA = eINSTANCE.getImageData();
+ EDataType IMAGE_DESCRIPTOR = eINSTANCE.getImageDescriptor();
/**
* The meta object literal for the '<em>ISkill Service</em>' data type.
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IUser.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IUser.java
index f177cef..786adf9 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IUser.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/IUser.java
@@ -5,7 +5,7 @@
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.jface.resource.ImageDescriptor;
/**
* <!-- begin-user-doc -->
@@ -158,10 +158,10 @@
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
- * @model kind="operation" dataType="org.eclipse.skills.model.ImageData"
+ * @model kind="operation" dataType="org.eclipse.skills.model.ImageDescriptor"
* @generated
*/
- ImageData getAvatar();
+ ImageDescriptor getAvatar();
/**
* <!-- begin-user-doc -->
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadge.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadge.java
index d2e6675..232338d 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadge.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadge.java
@@ -2,15 +2,17 @@
*/
package org.eclipse.skills.model.impl;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.skills.Activator;
+import org.eclipse.skills.Logger;
import org.eclipse.skills.model.IBadge;
import org.eclipse.skills.model.ISkillsPackage;
@@ -20,16 +22,16 @@
* The following features are implemented:
* </p>
* <ul>
- * <li>{@link org.eclipse.skills.model.impl.MBadge#getTitle <em>Title</em>}</li>
- * <li>{@link org.eclipse.skills.model.impl.MBadge#getImageURL <em>Image URL</em>}</li>
+ * <li>{@link org.eclipse.skills.model.impl.MBadge#getTitle <em>Title</em>}</li>
+ * <li>{@link org.eclipse.skills.model.impl.MBadge#getImageURL <em>Image URL</em>}</li>
* </ul>
*
* @generated
*/
public class MBadge extends MinimalEObjectImpl.Container implements IBadge {
/**
- * The default value of the '{@link #getTitle() <em>Title</em>}' attribute.
- * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * The default value of the '{@link #getTitle() <em>Title</em>}' attribute. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @see #getTitle()
* @generated
* @ordered
@@ -37,8 +39,8 @@
protected static final String TITLE_EDEFAULT = null;
/**
- * The cached value of the '{@link #getTitle() <em>Title</em>}' attribute.
- * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * The cached value of the '{@link #getTitle() <em>Title</em>}' attribute. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @see #getTitle()
* @generated
* @ordered
@@ -46,8 +48,8 @@
protected String title = TITLE_EDEFAULT;
/**
- * The default value of the '{@link #getImageURL() <em>Image URL</em>}' attribute.
- * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * The default value of the '{@link #getImageURL() <em>Image URL</em>}' attribute. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @see #getImageURL()
* @generated
* @ordered
@@ -55,8 +57,8 @@
protected static final String IMAGE_URL_EDEFAULT = null;
/**
- * The cached value of the '{@link #getImageURL() <em>Image URL</em>}' attribute.
- * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * The cached value of the '{@link #getImageURL() <em>Image URL</em>}' attribute. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @see #getImageURL()
* @generated
* @ordered
@@ -65,6 +67,7 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
protected MBadge() {
@@ -73,6 +76,7 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
@@ -82,6 +86,7 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
@@ -91,11 +96,12 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public void setTitle(String newTitle) {
- String oldTitle = title;
+ final String oldTitle = title;
title = newTitle;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.BADGE__TITLE, oldTitle, title));
@@ -103,6 +109,7 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
@@ -112,11 +119,12 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public void setImageURL(String newImageURL) {
- String oldImageURL = imageURL;
+ final String oldImageURL = imageURL;
imageURL = newImageURL;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.BADGE__IMAGE_URL, oldImageURL, imageURL));
@@ -124,77 +132,112 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @generated NOT
+ */
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ try {
+ return ImageDescriptor.createFromURL(new URL(getImageURL()));
+ } catch (final Exception e) {
+ Logger.warning(Activator.PLUGIN_ID, "Cannot load badge image data from \"" + getImageURL() + "\" for badge \"" + getTitle() + "\"");
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
- case ISkillsPackage.BADGE__TITLE:
- return getTitle();
- case ISkillsPackage.BADGE__IMAGE_URL:
- return getImageURL();
+ case ISkillsPackage.BADGE__TITLE:
+ return getTitle();
+ case ISkillsPackage.BADGE__IMAGE_URL:
+ return getImageURL();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
- case ISkillsPackage.BADGE__TITLE:
- setTitle((String)newValue);
- return;
- case ISkillsPackage.BADGE__IMAGE_URL:
- setImageURL((String)newValue);
- return;
+ case ISkillsPackage.BADGE__TITLE:
+ setTitle((String) newValue);
+ return;
+ case ISkillsPackage.BADGE__IMAGE_URL:
+ setImageURL((String) newValue);
+ return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public void eUnset(int featureID) {
switch (featureID) {
- case ISkillsPackage.BADGE__TITLE:
- setTitle(TITLE_EDEFAULT);
- return;
- case ISkillsPackage.BADGE__IMAGE_URL:
- setImageURL(IMAGE_URL_EDEFAULT);
- return;
+ case ISkillsPackage.BADGE__TITLE:
+ setTitle(TITLE_EDEFAULT);
+ return;
+ case ISkillsPackage.BADGE__IMAGE_URL:
+ setImageURL(IMAGE_URL_EDEFAULT);
+ return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public boolean eIsSet(int featureID) {
switch (featureID) {
- case ISkillsPackage.BADGE__TITLE:
- return TITLE_EDEFAULT == null ? title != null : !TITLE_EDEFAULT.equals(title);
- case ISkillsPackage.BADGE__IMAGE_URL:
- return IMAGE_URL_EDEFAULT == null ? imageURL != null : !IMAGE_URL_EDEFAULT.equals(imageURL);
+ case ISkillsPackage.BADGE__TITLE:
+ return TITLE_EDEFAULT == null ? title != null : !TITLE_EDEFAULT.equals(title);
+ case ISkillsPackage.BADGE__IMAGE_URL:
+ return IMAGE_URL_EDEFAULT == null ? imageURL != null : !IMAGE_URL_EDEFAULT.equals(imageURL);
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
+ switch (operationID) {
+ case ISkillsPackage.BADGE___GET_IMAGE_DESCRIPTOR:
+ return getImageDescriptor();
+ }
+ return super.eInvoke(operationID, arguments);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public String toString() {
- if (eIsProxy()) return super.toString();
+ if (eIsProxy())
+ return super.toString();
- StringBuilder result = new StringBuilder(super.toString());
+ final StringBuilder result = new StringBuilder(super.toString());
result.append(" (title: ");
result.append(title);
result.append(", imageURL: ");
@@ -202,24 +245,4 @@
result.append(')');
return result.toString();
}
-
- /**
- * @generated NOT
- */
- @Override
- public byte[] getImageData() throws IOException {
-
- final byte[] buffer = new byte[8 * 1024];
- final ByteArrayOutputStream data = new ByteArrayOutputStream();
- try (InputStream in = new URL(getImageURL()).openStream()) {
- int chars = in.read(buffer);
- while (chars > 0) {
- data.write(buffer, 0, chars);
- chars = in.read(buffer);
- }
- }
-
- return data.toByteArray();
- }
-
} // MBadge
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadgeReward.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadgeReward.java
index d0f3d70..c70ec0d 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadgeReward.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MBadgeReward.java
@@ -27,15 +27,15 @@
* The following features are implemented:
* </p>
* <ul>
- * <li>{@link org.eclipse.skills.model.impl.MBadgeReward#getBadge <em>Badge</em>}</li>
+ * <li>{@link org.eclipse.skills.model.impl.MBadgeReward#getBadge <em>Badge</em>}</li>
* </ul>
*
* @generated
*/
public class MBadgeReward extends MinimalEObjectImpl.Container implements IBadgeReward {
/**
- * The cached value of the '{@link #getBadge() <em>Badge</em>}' containment reference.
- * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * The cached value of the '{@link #getBadge() <em>Badge</em>}' containment reference. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @see #getBadge()
* @generated
* @ordered
@@ -44,6 +44,7 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
protected MBadgeReward() {
@@ -52,6 +53,7 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
@@ -61,6 +63,7 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
@@ -70,20 +73,25 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
public NotificationChain basicSetBadge(IBadge newBadge, NotificationChain msgs) {
- IBadge oldBadge = badge;
+ final IBadge oldBadge = badge;
badge = newBadge;
if (eNotificationRequired()) {
- ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ISkillsPackage.BADGE_REWARD__BADGE, oldBadge, newBadge);
- if (msgs == null) msgs = notification; else msgs.add(notification);
+ final ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ISkillsPackage.BADGE_REWARD__BADGE, oldBadge, newBadge);
+ if (msgs == null)
+ msgs = notification;
+ else
+ msgs.add(notification);
}
return msgs;
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
@@ -91,13 +99,13 @@
if (newBadge != badge) {
NotificationChain msgs = null;
if (badge != null)
- msgs = ((InternalEObject)badge).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ISkillsPackage.BADGE_REWARD__BADGE, null, msgs);
+ msgs = ((InternalEObject) badge).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ISkillsPackage.BADGE_REWARD__BADGE, null, msgs);
if (newBadge != null)
- msgs = ((InternalEObject)newBadge).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ISkillsPackage.BADGE_REWARD__BADGE, null, msgs);
+ msgs = ((InternalEObject) newBadge).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ISkillsPackage.BADGE_REWARD__BADGE, null, msgs);
msgs = basicSetBadge(newBadge, msgs);
- if (msgs != null) msgs.dispatch();
- }
- else if (eNotificationRequired())
+ if (msgs != null)
+ msgs.dispatch();
+ } else if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.BADGE_REWARD__BADGE, newBadge, newBadge));
}
@@ -112,7 +120,8 @@
try {
// try to clone image to a local folder
- SkillService.getInstance().storeResource(getBadge().getTitle(), getBadge().getImageData());
+ SkillService.getInstance().storeResource(getBadge().getTitle(), getBadge().getImageDescriptor().getImageData(100).data);
+
} catch (final IOException e) {
Logger.error(Activator.PLUGIN_ID, "Could not copy badge to local folder", e);
}
@@ -122,81 +131,87 @@
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
switch (featureID) {
- case ISkillsPackage.BADGE_REWARD__BADGE:
- return basicSetBadge(null, msgs);
+ case ISkillsPackage.BADGE_REWARD__BADGE:
+ return basicSetBadge(null, msgs);
}
return super.eInverseRemove(otherEnd, featureID, msgs);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
- case ISkillsPackage.BADGE_REWARD__BADGE:
- return getBadge();
+ case ISkillsPackage.BADGE_REWARD__BADGE:
+ return getBadge();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
- case ISkillsPackage.BADGE_REWARD__BADGE:
- setBadge((IBadge)newValue);
- return;
+ case ISkillsPackage.BADGE_REWARD__BADGE:
+ setBadge((IBadge) newValue);
+ return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public void eUnset(int featureID) {
switch (featureID) {
- case ISkillsPackage.BADGE_REWARD__BADGE:
- setBadge((IBadge)null);
- return;
+ case ISkillsPackage.BADGE_REWARD__BADGE:
+ setBadge((IBadge) null);
+ return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public boolean eIsSet(int featureID) {
switch (featureID) {
- case ISkillsPackage.BADGE_REWARD__BADGE:
- return badge != null;
+ case ISkillsPackage.BADGE_REWARD__BADGE:
+ return badge != null;
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
* @generated
*/
@Override
public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
switch (operationID) {
- case ISkillsPackage.BADGE_REWARD___PAY_OUT__IUSER:
- payOut((IUser)arguments.get(0));
- return null;
+ case ISkillsPackage.BADGE_REWARD___PAY_OUT__IUSER:
+ payOut((IUser) arguments.get(0));
+ return null;
}
return super.eInvoke(operationID, arguments);
}
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsFactory.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsFactory.java
index 75e967c..b644860 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsFactory.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsFactory.java
@@ -16,7 +16,6 @@
import org.eclipse.skills.dependencies.CustomDependencyDefinition;
import org.eclipse.skills.model.*;
import org.eclipse.skills.service.ISkillService;
-import org.eclipse.swt.graphics.ImageData;
/**
* <!-- begin-user-doc -->
@@ -102,8 +101,6 @@
return createDateFromString(eDataType, initialValue);
case ISkillsPackage.CUSTOM_DEPENDENCY_DEFINITION:
return createCustomDependencyDefinitionFromString(eDataType, initialValue);
- case ISkillsPackage.IMAGE_DATA:
- return createImageDataFromString(eDataType, initialValue);
case ISkillsPackage.ISKILL_SERVICE:
return createISkillServiceFromString(eDataType, initialValue);
default:
@@ -125,8 +122,6 @@
return convertDateToString(eDataType, instanceValue);
case ISkillsPackage.CUSTOM_DEPENDENCY_DEFINITION:
return convertCustomDependencyDefinitionToString(eDataType, instanceValue);
- case ISkillsPackage.IMAGE_DATA:
- return convertImageDataToString(eDataType, instanceValue);
case ISkillsPackage.ISKILL_SERVICE:
return convertISkillServiceToString(eDataType, instanceValue);
default:
@@ -426,24 +421,6 @@
* <!-- end-user-doc -->
* @generated
*/
- public ImageData createImageDataFromString(EDataType eDataType, String initialValue) {
- return (ImageData)super.createFromString(eDataType, initialValue);
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public String convertImageDataToString(EDataType eDataType, Object instanceValue) {
- return super.convertToString(eDataType, instanceValue);
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
public ISkillService createISkillServiceFromString(EDataType eDataType, String initialValue) {
return (ISkillService)super.createFromString(eDataType, initialValue);
}
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsPackage.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsPackage.java
index 4bc0379..5689bf8 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsPackage.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MSkillsPackage.java
@@ -14,6 +14,7 @@
import org.eclipse.emf.ecore.impl.EPackageImpl;
+import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.skills.dependencies.CustomDependencyDefinition;
import org.eclipse.skills.model.IAndDependency;
import org.eclipse.skills.model.IBadge;
@@ -46,7 +47,6 @@
import org.eclipse.skills.model.IUserTask;
import org.eclipse.skills.model.LevelName;
import org.eclipse.skills.service.ISkillService;
-import org.eclipse.swt.graphics.ImageData;
/**
* <!-- begin-user-doc -->
@@ -270,7 +270,7 @@
* <!-- end-user-doc -->
* @generated
*/
- private EDataType imageDataEDataType = null;
+ private EDataType imageDescriptorEDataType = null;
/**
* <!-- begin-user-doc -->
@@ -546,6 +546,16 @@
* @generated
*/
@Override
+ public EOperation getBadge__GetImageDescriptor() {
+ return badgeEClass.getEOperations().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
public EClass getUser() {
return userEClass;
}
@@ -1366,8 +1376,8 @@
* @generated
*/
@Override
- public EDataType getImageData() {
- return imageDataEDataType;
+ public EDataType getImageDescriptor() {
+ return imageDescriptorEDataType;
}
/**
@@ -1432,6 +1442,7 @@
badgeEClass = createEClass(BADGE);
createEAttribute(badgeEClass, BADGE__TITLE);
createEAttribute(badgeEClass, BADGE__IMAGE_URL);
+ createEOperation(badgeEClass, BADGE___GET_IMAGE_DESCRIPTOR);
userEClass = createEClass(USER);
createEAttribute(userEClass, USER__NAME);
@@ -1541,7 +1552,7 @@
// Create data types
dateEDataType = createEDataType(DATE);
customDependencyDefinitionEDataType = createEDataType(CUSTOM_DEPENDENCY_DEFINITION);
- imageDataEDataType = createEDataType(IMAGE_DATA);
+ imageDescriptorEDataType = createEDataType(IMAGE_DESCRIPTOR);
iSkillServiceEDataType = createEDataType(ISKILL_SERVICE);
}
@@ -1621,6 +1632,8 @@
initEAttribute(getBadge_Title(), ecorePackage.getEString(), "title", null, 0, 1, IBadge.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
initEAttribute(getBadge_ImageURL(), ecorePackage.getEString(), "imageURL", null, 0, 1, IBadge.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+ initEOperation(getBadge__GetImageDescriptor(), this.getImageDescriptor(), "getImageDescriptor", 0, 1, IS_UNIQUE, IS_ORDERED);
+
initEClass(userEClass, IUser.class, "User", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
initEAttribute(getUser_Name(), ecorePackage.getEString(), "name", null, 0, 1, IUser.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
initEReference(getUser_Skills(), this.getSkill(), null, "skills", null, 0, -1, IUser.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
@@ -1638,7 +1651,7 @@
op = initEOperation(getUser__Consume__IReward(), null, "consume", 0, 1, IS_UNIQUE, IS_ORDERED);
addEParameter(op, this.getReward(), "reward", 0, 1, IS_UNIQUE, IS_ORDERED);
- initEOperation(getUser__GetAvatar(), this.getImageData(), "getAvatar", 0, 1, IS_UNIQUE, IS_ORDERED);
+ initEOperation(getUser__GetAvatar(), this.getImageDescriptor(), "getAvatar", 0, 1, IS_UNIQUE, IS_ORDERED);
op = initEOperation(getUser__GetSkill__String(), this.getSkill(), "getSkill", 0, 1, IS_UNIQUE, IS_ORDERED);
addEParameter(op, ecorePackage.getEString(), "name", 0, 1, IS_UNIQUE, IS_ORDERED);
@@ -1756,7 +1769,7 @@
// Initialize data types
initEDataType(dateEDataType, Date.class, "Date", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
initEDataType(customDependencyDefinitionEDataType, CustomDependencyDefinition.class, "CustomDependencyDefinition", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
- initEDataType(imageDataEDataType, ImageData.class, "ImageData", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
+ initEDataType(imageDescriptorEDataType, ImageDescriptor.class, "ImageDescriptor", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
initEDataType(iSkillServiceEDataType, ISkillService.class, "ISkillService", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
// Create resource
diff --git a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MUser.java b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MUser.java
index 436997f..32462c1 100644
--- a/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MUser.java
+++ b/plugins/org.eclipse.skills/src-gen/org/eclipse/skills/model/impl/MUser.java
@@ -2,8 +2,8 @@
*/
package org.eclipse.skills.model.impl;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Objects;
@@ -19,7 +19,9 @@
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.skills.Activator;
+import org.eclipse.skills.Logger;
import org.eclipse.skills.model.IBadge;
import org.eclipse.skills.model.IReward;
import org.eclipse.skills.model.ISkill;
@@ -303,34 +305,34 @@
}
/**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * Get the image data for the chosen avatar.
*
* @generated NOT
*/
@Override
- public ImageData getAvatar() {
- try {
- final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
- if (skillService.hasResource(ISkillService.RESOURCE_AVATAR)) {
- return new ImageData(new ByteArrayInputStream(skillService.loadResource(ISkillService.RESOURCE_AVATAR)));
+ public ImageDescriptor getAvatar() {
+ final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
+ if (skillService.hasResource(ISkillService.RESOURCE_AVATAR)) {
+ try (InputStream input = skillService.openResource(ISkillService.RESOURCE_AVATAR)) {
+ final ImageData imageData = new ImageData(input);
+ return ImageDescriptor.createFromImageData(imageData);
- } else {
+ } catch (final IOException e) {
+ Logger.warning(Activator.PLUGIN_ID, "Failed to load avatar image", e);
+ }
+
+ } else {
+ try {
final byte[] imageData = AvatarCreator.getRandomAvatarData();
skillService.storeResource(ISkillService.RESOURCE_AVATAR, imageData);
return getAvatar();
- }
-
- } catch (final IOException e) {
- // avatar cannot be loaded
- try {
- return new ImageData(Activator.getDefault().loadResource("/resources/broken_image.png"));
- } catch (final IOException e1) {
- // giving up
- // FIXME null is bad here
- return null;
+ } catch (final IOException e) {
+ Logger.warning(Activator.PLUGIN_ID, "Failed to store a new avatar image", e);
}
}
+
+ return ImageDescriptor.getMissingImageDescriptor();
}
/**
@@ -513,5 +515,4 @@
result.append(')');
return result.toString();
}
-
} // MUser
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/ISkillService.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/ISkillService.java
index 150eaa2..b410419 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/ISkillService.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/ISkillService.java
@@ -20,6 +20,7 @@
import org.eclipse.skills.model.ITask;
import org.eclipse.skills.model.IUser;
import org.eclipse.skills.model.IUserTask;
+import org.eclipse.skills.service.storage.IDataStorage;
/**
* Global service to manage user statistics, available quests and skills. To get the service instance use
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/SkillService.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/SkillService.java
index 97eb38f..5f0dd6f 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/SkillService.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/SkillService.java
@@ -35,6 +35,7 @@
import org.eclipse.skills.model.ITask;
import org.eclipse.skills.model.IUser;
import org.eclipse.skills.model.IUserTask;
+import org.eclipse.skills.service.storage.DataStorageProxy;
import org.eclipse.skills.service.storage.WorkspaceDataStorage;
import org.eclipse.ui.PlatformUI;
import org.osgi.service.event.Event;
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/UserStorage.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/UserStorage.java
index f4e1395..4b310d6 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/UserStorage.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/UserStorage.java
@@ -31,6 +31,8 @@
import org.eclipse.skills.Logger;
import org.eclipse.skills.model.ISkillsPackage;
import org.eclipse.skills.model.IUser;
+import org.eclipse.skills.service.storage.DataStorageProxy;
+import org.eclipse.skills.service.storage.IDataStorage;
public class UserStorage extends DataStorageProxy {
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/DataStorageProxy.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/DataStorageProxy.java
similarity index 82%
rename from plugins/org.eclipse.skills/src/org/eclipse/skills/service/DataStorageProxy.java
rename to plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/DataStorageProxy.java
index e3fbb11..f78e4aa 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/DataStorageProxy.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/DataStorageProxy.java
@@ -11,10 +11,11 @@
* Christian Pontesegger - initial API and implementation
*******************************************************************************/
-package org.eclipse.skills.service;
+package org.eclipse.skills.service.storage;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
public class DataStorageProxy implements IDataStorage {
@@ -52,4 +53,12 @@
fBaseStorage = baseStorage;
}
+
+ @Override
+ public InputStream openResource(String name) throws IOException {
+ if (hasResource(name))
+ return getStorage().openResource(name);
+
+ throw new FileNotFoundException(String.format("Resource \"%s\" could not be found", name));
+ }
}
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/IDataStorage.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/IDataStorage.java
similarity index 79%
rename from plugins/org.eclipse.skills/src/org/eclipse/skills/service/IDataStorage.java
rename to plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/IDataStorage.java
index 358cb42..3371d2b 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/IDataStorage.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/IDataStorage.java
@@ -11,9 +11,10 @@
* Christian Pontesegger - initial API and implementation
*******************************************************************************/
-package org.eclipse.skills.service;
+package org.eclipse.skills.service.storage;
import java.io.IOException;
+import java.io.InputStream;
public interface IDataStorage {
@@ -38,10 +39,22 @@
* name of resource in storage
* @throws IOException
* when data cannot be loaded
+ * @return resource binary data
*/
public byte[] loadResource(String name) throws IOException;
/**
+ * Get an input stream to a resource.
+ *
+ * @param name
+ * name of resource in storage
+ * @throws IOException
+ * when data cannot be loaded
+ * @return resource input stream
+ */
+ InputStream openResource(String name) throws IOException;
+
+ /**
* Check if a resource exists in the storage.
*
* @param name
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/WorkspaceDataStorage.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/WorkspaceDataStorage.java
index db6e27a..d8cb415 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/WorkspaceDataStorage.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/service/storage/WorkspaceDataStorage.java
@@ -14,7 +14,9 @@
package org.eclipse.skills.service.storage;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -22,7 +24,6 @@
import org.eclipse.core.runtime.IPath;
import org.eclipse.skills.Activator;
-import org.eclipse.skills.service.IDataStorage;
public class WorkspaceDataStorage implements IDataStorage {
@@ -34,7 +35,7 @@
@Override
public void storeResource(String name, byte[] data) throws IOException {
final Path target = Paths.get(getUserStorageLocation().getAbsolutePath(), name);
- Files.write(target, data, StandardOpenOption.CREATE);
+ Files.write(target, data, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
@Override
@@ -44,6 +45,12 @@
}
@Override
+ public InputStream openResource(String name) throws IOException {
+ final Path target = Paths.get(getUserStorageLocation().getAbsolutePath(), name);
+ return new FileInputStream(target.toFile());
+ }
+
+ @Override
public boolean hasResource(String name) {
final Path target = Paths.get(getUserStorageLocation().getAbsolutePath(), name);
return target.toFile().exists();
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/BadgesComposite.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/BadgesComposite.java
index 7be92ac..48febc1 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/BadgesComposite.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/BadgesComposite.java
@@ -13,39 +13,22 @@
package org.eclipse.skills.ui.views.character;
-import java.util.Collection;
-
+import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.skills.model.IBadge;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
-import org.eclipse.wb.swt.SWTResourceManager;
public class BadgesComposite extends Composite {
- public BadgesComposite(Composite parent, int style) {
+ public BadgesComposite(Composite parent, int style, ResourceManager resourceManager) {
super(parent, style | SWT.H_SCROLL);
setLayout(new FillLayout(SWT.HORIZONTAL));
- setBadges(null);
+ for (final IBadge badge : CharacterView.getUser().getBadges()) {
+ final Label badgeLabel = new Label(this, SWT.NONE);
+ badgeLabel.setImage(resourceManager.createImage(badge.getImageDescriptor()));
+ }
}
-
- public void setBadges(Collection<IBadge> badges) {
- // discard old content
- for (final Control child : getChildren())
- child.dispose();
-
- // populate new content
- final Label lblNewLabel_4 = new Label(this, SWT.NONE);
- lblNewLabel_4.setImage(SWTResourceManager.getImage("/home/christian/badge2.png"));
-
- final Label lblNewLabel_3 = new Label(this, SWT.NONE);
- lblNewLabel_3.setImage(SWTResourceManager.getImage("/home/christian/badge1.png"));
-
- final Label lblNewLabel_5 = new Label(this, SWT.NONE);
- lblNewLabel_5.setImage(SWTResourceManager.getImage("/home/christian/badge3.png"));
- }
-
}
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterComposite.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterComposite.java
new file mode 100644
index 0000000..80aad82
--- /dev/null
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterComposite.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.skills.ui.views.character;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.skills.Activator;
+import org.eclipse.skills.Logger;
+import org.eclipse.skills.service.AvatarCreator;
+import org.eclipse.skills.service.ISkillService;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.PlatformUI;
+
+public class CharacterComposite extends Composite {
+
+ public CharacterComposite(Composite parent, int style, ResourceManager resourceManager) {
+ super(parent, style);
+
+ setLayout(new GridLayout(2, false));
+
+ final Label lblCharacterImage = createImageLabel(resourceManager);
+ createLoadImageLink(lblCharacterImage, resourceManager);
+ createRandomImageLink(lblCharacterImage, resourceManager);
+ }
+
+ private Label createImageLabel(ResourceManager resourceManager) {
+ final Label avatarLabel = new Label(this, SWT.NONE);
+ avatarLabel.setLayoutData(GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(false, true).span(2, 1).indent(0, 20).create());
+
+ updateAvatarImage(avatarLabel, resourceManager);
+
+ return avatarLabel;
+ }
+
+ private void createRandomImageLink(Label lblCharacterImage, ResourceManager resourceManager) {
+ final Link lnkRandomImage = new Link(this, SWT.NONE);
+ lnkRandomImage.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+ lnkRandomImage.setText("<a>Random image</a>");
+ lnkRandomImage.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseDown(MouseEvent e) {
+
+ try {
+ storeAvatarImage(AvatarCreator.getRandomAvatarData());
+
+ updateAvatarImage(lblCharacterImage, resourceManager);
+
+ } catch (final IOException ex) {
+ Logger.error(Activator.PLUGIN_ID, "Could not load random avatar image", ex);
+ }
+ }
+
+ });
+ }
+
+ private void createLoadImageLink(Label lblCharacterImage, ResourceManager resourceManager) {
+ final Link lnkLoadImage = new Link(this, SWT.NONE);
+ lnkLoadImage.setText("<a>Load image...</a>");
+ lnkLoadImage.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseDown(MouseEvent e) {
+ final FileDialog fileDialog = new FileDialog(Display.getDefault().getActiveShell());
+ final String location = fileDialog.open();
+ if (location != null) {
+ try {
+ final File imageFile = new File(location);
+ final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
+ skillService.storeResource(ISkillService.RESOURCE_AVATAR, Files.readAllBytes(imageFile.toPath()));
+
+ updateAvatarImage(lblCharacterImage, resourceManager);
+
+ } catch (final IOException ex) {
+ Logger.error(Activator.PLUGIN_ID, "Could not load avatar image from file: " + location, ex);
+ }
+ }
+ }
+
+ });
+ }
+
+ private void storeAvatarImage(final byte[] imageData) throws IOException {
+ final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
+ skillService.storeResource(ISkillService.RESOURCE_AVATAR, imageData);
+ }
+
+ private void updateAvatarImage(Label avatarLabel, ResourceManager resourceManager) {
+ avatarLabel.setImage(getAvatarImage(resourceManager));
+ avatarLabel.getParent().layout(true);
+ }
+
+ private Image getAvatarImage(ResourceManager resourceManager) {
+ final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
+ if (skillService != null)
+ return resourceManager.createImage(skillService.getUser().getAvatar());
+
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterSheet.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterSheet.java
deleted file mode 100644
index 4f34caf..0000000
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterSheet.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2020 Christian Pontesegger and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Christian Pontesegger - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.skills.ui.views.character;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.skills.Activator;
-import org.eclipse.skills.Logger;
-import org.eclipse.skills.model.ISkill;
-import org.eclipse.skills.model.ISkillsFactory;
-import org.eclipse.skills.model.IUser;
-import org.eclipse.skills.service.AvatarCreator;
-import org.eclipse.skills.service.ISkillService;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.ProgressBar;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.ViewPart;
-import org.eclipse.wb.swt.SWTResourceManager;
-
-public class CharacterSheet extends ViewPart {
-
- /**
- * Creates fake user data. Needed for developers when working with the SWT designer as we do not have a real service running there.
- *
- * @return fake user instance
- */
- public static IUser createDummyUser() {
- final IUser user = ISkillsFactory.eINSTANCE.createUser();
-
- final ISkill xp = ISkillsFactory.eINSTANCE.createSkill();
- xp.setName("XP");
- xp.setExperience(12345);
- xp.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression());
-
- user.setExperience(xp);
-
- final ISkill flexibility = ISkillsFactory.eINSTANCE.createSkill();
- flexibility.setName("Flexibility");
- flexibility.setExperience(445);
- flexibility.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression());
- user.getSkills().add(flexibility);
-
- final ISkill knowledge = ISkillsFactory.eINSTANCE.createSkill();
- knowledge.setName("Knowledge");
- knowledge.setExperience(5774);
- knowledge.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression());
- user.getSkills().add(knowledge);
-
- final ISkill scripting = ISkillsFactory.eINSTANCE.createSkill();
- scripting.setName("Scripting");
- scripting.setExperience(1111);
- scripting.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression());
- user.getSkills().add(scripting);
-
- user.setName("Hendrik");
- user.setImageLocation("platform:/plugin/" + Activator.PLUGIN_ID + "/resources/defaultAvatars/gentleman.png");
-
- return user;
- }
-
- private Label flblCharacterImage;
- private SkillsComposite fskillsComposite;
- private Composite fDataComposite;
- private Label fLblTitle;
-
- public CharacterSheet() {
- }
-
- @Override
- public void createPartControl(Composite parent) {
-
- final Composite composite = new Composite(parent, SWT.NONE);
- composite.setLayout(new GridLayout(3, false));
-
- fLblTitle = new Label(composite, SWT.NONE);
- fLblTitle.setFont(SWTResourceManager.getFont("Cantarell", 24, SWT.BOLD));
- fLblTitle.setForeground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND));
- final GridData gd_lblNewLabel_2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1);
- gd_lblNewLabel_2.horizontalIndent = 20;
- fLblTitle.setLayoutData(gd_lblNewLabel_2);
- fLblTitle.setText("Scripting Expert");
-
- flblCharacterImage = new Label(composite, SWT.NONE);
- flblCharacterImage.setImage(getAvatarImage());
- final GridData gd_lblCharacterImage = new GridData(SWT.LEFT, SWT.TOP, false, true, 2, 1);
- gd_lblCharacterImage.verticalIndent = 20;
- flblCharacterImage.setLayoutData(gd_lblCharacterImage);
-
- fDataComposite = new Composite(composite, SWT.NONE);
- fDataComposite.setLayout(new GridLayout(3, false));
- fDataComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
- new Label(fDataComposite, SWT.NONE);
- new Label(fDataComposite, SWT.NONE);
- new Label(fDataComposite, SWT.NONE);
-
- createSkillComponent(getUser().getExperience());
-
- final Label label_1 = new Label(fDataComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
- final GridData gd_label_1 = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1);
- gd_label_1.verticalIndent = 20;
- label_1.setLayoutData(gd_label_1);
-
- final Label lblNewLabel_6 = new Label(fDataComposite, SWT.NONE);
- lblNewLabel_6.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
- lblNewLabel_6.setText("Your Skills:");
- new Label(fDataComposite, SWT.NONE);
- new Label(fDataComposite, SWT.NONE);
-
- fskillsComposite = new SkillsComposite(fDataComposite, SWT.NONE);
- fskillsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
- new Label(fDataComposite, SWT.NONE);
-
- final BadgesComposite badgesComposite = new BadgesComposite(fDataComposite, SWT.H_SCROLL);
- final FillLayout fillLayout = (FillLayout) badgesComposite.getLayout();
- fillLayout.spacing = 20;
- badgesComposite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
- new Label(fDataComposite, SWT.NONE);
-
- final Label label = new Label(fDataComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
- label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
- new Label(fDataComposite, SWT.NONE);
-
- final Link link = new Link(composite, SWT.NONE);
- link.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseDown(MouseEvent e) {
- final FileDialog fileDialog = new FileDialog(Display.getDefault().getActiveShell());
- final String location = fileDialog.open();
- if (location != null) {
- try {
- final File imageFile = new File(location);
- final Image image = ImageDescriptor.createFromURL(imageFile.toURL()).createImage();
- // FIXME resource handling
- flblCharacterImage.setImage(image);
- flblCharacterImage.getParent().layout(true);
-
- final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
- skillService.storeResource(ISkillService.RESOURCE_AVATAR, Files.readAllBytes(imageFile.toPath()));
-
- } catch (final IOException ex) {
- Logger.error(Activator.PLUGIN_ID, "Could not load avatar image from file: " + location, ex);
- }
- }
- }
- });
- link.setText("<a>Load image...</a>");
-
- final Link link_1 = new Link(composite, SWT.NONE);
- link_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- link_1.setText("<a>Random image</a>");
- link_1.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseDown(MouseEvent e) {
-
- try {
- final byte[] imageData = AvatarCreator.getRandomAvatarData();
- final Image image = new Image(Display.getDefault(), new ImageData(new ByteArrayInputStream(imageData)));
- // FIXME resource handling
- flblCharacterImage.setImage(image);
- flblCharacterImage.getParent().layout(true);
-
- final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
- skillService.storeResource(ISkillService.RESOURCE_AVATAR, imageData);
-
- } catch (final IOException ex) {
- Logger.error(Activator.PLUGIN_ID, "Could not load random avatar image", ex);
- }
- }
- });
- new Label(composite, SWT.NONE);
-
- loadUserData();
- }
-
- private void createSkillComponent(ISkill skill) {
- final Label lblNewLabel = new Label(fDataComposite, SWT.NONE);
- lblNewLabel.setText(skill.getName() + ":");
-
- final ProgressBar prgExperience = new ProgressBar(fDataComposite, SWT.SMOOTH);
- prgExperience.setMinimum(100);
- prgExperience.setMaximum(1000);
- prgExperience.setSelection(100);
- prgExperience.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- prgExperience.setToolTipText("2523 / 3000");
-
- final Label lblNewLabel_1 = new Label(fDataComposite, SWT.NONE);
- lblNewLabel_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- lblNewLabel_1.setText("Level " + skill.getProgression().getLevel(skill.getExperience()));
- }
-
- /**
- * Get the avatar image.
- *
- * @return
- */
- private Image getAvatarImage() {
- // FIXME add resource handling
- final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
- if (skillService != null)
- return new Image(Display.getDefault(), skillService.getUser().getAvatar());
-
- return SWTResourceManager.getImage("/home/christian/character.png");
- }
-
- @Override
- public void setFocus() {
- }
-
- public IUser getUser() {
- final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
- if (skillService != null)
- return skillService.getUser();
-
- // needed when used in development mode in SWT designer
- return createDummyUser();
- }
-
- public void loadUserData() {
- final IUser user = getUser();
- final String imageLocation = user.getImageLocation();
- if (imageLocation != null) {
- // FIXME add resource handling
- try {
- final ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(new URL(imageLocation));
- flblCharacterImage.setImage(imageDescriptor.createImage());
-
- } catch (final MalformedURLException e) {
- Logger.error(Activator.PLUGIN_ID, "Cannot load character image from \"" + imageLocation + "\"", e);
- }
- }
-
- fLblTitle.setText(user.getName() + ", an expert (TODO)");
-
- for (final ISkill skill : getSkillsSortedByProgress(user))
- createSkillComponent(skill);
-
- fskillsComposite.setSkills(user.getSkills());
- }
-
- private List<ISkill> getSkillsSortedByProgress(final IUser user) {
- final List<ISkill> skills = new ArrayList<>(user.getSkills());
- Collections.sort(skills, (o1, o2) -> {
- if (o1.getProgression().getLevel(o1.getExperience()) == o2.getProgression().getLevel(o2.getExperience()))
- return o2.getExperience() - o1.getExperience();
-
- return o2.getProgression().getLevel(o2.getExperience()) - o1.getProgression().getLevel(o1.getExperience());
- });
-
- return skills;
- }
-}
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterView.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterView.java
new file mode 100644
index 0000000..6634627
--- /dev/null
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/CharacterView.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.skills.ui.views.character;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.skills.model.IUser;
+import org.eclipse.skills.service.ISkillService;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.wb.swt.SWTResourceManager;
+
+public class CharacterView extends ViewPart {
+
+ public static IUser getUser() {
+ final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
+ if (skillService != null)
+ return skillService.getUser();
+
+ return null;
+ }
+
+ private StatsComposite fStatsComposite;
+ private LocalResourceManager fResourceManager;
+
+ public CharacterView() {
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+
+ final Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+
+ fResourceManager = new LocalResourceManager(JFaceResources.getResources(), composite);
+
+ final Label lblTitle = addTitle(composite);
+
+ final CharacterComposite characterComposite = new CharacterComposite(composite, SWT.NONE, fResourceManager);
+ characterComposite.setLayoutData(GridDataFactory.fillDefaults().grab(false, true).create());
+
+ fStatsComposite = new StatsComposite(composite, SWT.NONE, fResourceManager);
+ fStatsComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
+ }
+
+ private Label addTitle(final Composite parent) {
+ // FIXME use default font for headers
+ final Label lblTitle = new Label(parent, SWT.NONE);
+ lblTitle.setFont(SWTResourceManager.getFont("Cantarell", 24, SWT.BOLD));
+ lblTitle.setForeground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND));
+ lblTitle.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(2, 1).indent(20, 0).create());
+ lblTitle.setText(getUser().getName() + ", an expert (TODO)");
+
+ return lblTitle;
+ }
+
+ @Override
+ public void setFocus() {
+ }
+}
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/SkillsComposite.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/SkillsComposite.java
index 9b84fec..f19afb7 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/SkillsComposite.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/SkillsComposite.java
@@ -13,49 +13,126 @@
package org.eclipse.skills.ui.views.character;
+import java.time.Duration;
import java.util.Collection;
+import java.util.List;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.util.Throttler;
import org.eclipse.skills.model.ISkill;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ProgressBar;
public class SkillsComposite extends Composite {
- public SkillsComposite(Composite parent, int style) {
+ private static final String FLAG_WITH_PROGRESSBAR = "hasProgressbar";
+
+ private final boolean fShowProgress;
+
+ private final Throttler fUiUpdateThrottler = new Throttler(Display.getDefault(), Duration.ofMillis(500), this::updateControls);
+
+ private final Adapter fSkillAdapter = new SkillAdapter();
+
+ public SkillsComposite(Composite parent, int style, List<ISkill> skills, boolean showProgress) {
super(parent, style);
- setLayout(new GridLayout(3, false));
+ fShowProgress = showProgress;
+
+ setLayout(new GridLayout(showProgress ? 3 : 2, false));
+
+ setSkills(skills);
}
public void setSkills(Collection<ISkill> skills) {
- // discard old content
- for (final Control child : getChildren())
- child.dispose();
- // populate new content
for (final ISkill skill : skills) {
- final Label lblTitle = new Label(this, SWT.NONE);
- lblTitle.setText(skill.getName());
- // FIXME needs better getter for plain text/ abstract
- lblTitle.setToolTipText(skill.getDescription().toString());
-
- final ProgressBar progressBar = new ProgressBar(this, SWT.NONE);
- progressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- progressBar.setMinimum(0);
- progressBar.setMaximum(100);
- progressBar.setSelection(skill.getExperience());
-
- final Label lblLevel = new Label(this, SWT.NONE);
- // FIXME get correct level
- lblLevel.setText("Lvl 7");
+ createSkillElement(this, skill);
+ skill.eAdapters().add(fSkillAdapter);
}
// trigger fresh layout
getParent().layout();
}
+
+ private void createSkillElement(Composite parent, ISkill skill) {
+ final Label lblTitle = new Label(parent, SWT.NONE);
+ lblTitle.setText(skill.getName());
+ lblTitle.setToolTipText(skill.getDescription().getText());
+ lblTitle.setLayoutData(GridDataFactory.fillDefaults().create());
+
+ if (fShowProgress) {
+ final ProgressBar progressBar = new ProgressBar(parent, SWT.NONE);
+ progressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ progressBar.setData(skill);
+ updateControl(progressBar, skill);
+
+ final Label lblLevel = new Label(parent, SWT.NONE);
+ lblLevel.setData(skill);
+ lblLevel.setData(FLAG_WITH_PROGRESSBAR, true);
+ updateControl(lblLevel, skill);
+
+ } else {
+
+ final Label lblLevel = new Label(parent, SWT.NONE);
+ lblLevel.setData(skill);
+ lblLevel.setData(FLAG_WITH_PROGRESSBAR, false);
+ lblLevel.setLayoutData(GridDataFactory.fillDefaults().indent(20, 0).create());
+ updateControl(lblLevel, skill);
+ }
+ }
+
+ public void updateControls() {
+ for (final Control control : getChildren()) {
+ if (control.getData() instanceof ISkill)
+ updateControl(control, (ISkill) control.getData());
+ }
+ }
+
+ public void updateControl(Control control, ISkill skill) {
+ final int level = skill.getProgression().getLevel(skill.getExperience());
+ final int currentLevelMinXP = skill.getProgression().getMinimumXpForLevel(level);
+ final int nextLevelMinXP = skill.getProgression().getMinimumXpForLevel(level + 1);
+
+ if (control instanceof Label) {
+ if (hasProgressbar(control)) {
+ ((Label) control).setText(String.format("Level %d", level));
+ ((Label) control).setToolTipText(
+ String.format("Earn %d more %s to reach level %d", (nextLevelMinXP - skill.getExperience()), skill.getName(), level + 1));
+
+ } else {
+ ((Label) control).setText(String.format("%d", level));
+ ((Label) control).setToolTipText(
+ String.format("Earn %d more %s points to reach level %d", (nextLevelMinXP - skill.getExperience()), skill.getName(), level + 1));
+ }
+
+ } else if (control instanceof ProgressBar) {
+ ((ProgressBar) control).setMinimum(currentLevelMinXP);
+ ((ProgressBar) control).setMaximum(nextLevelMinXP);
+ ((ProgressBar) control).setSelection(skill.getExperience());
+ ((ProgressBar) control).setToolTipText(String.format("%d %s XP", skill.getExperience(), skill.getName()));
+ }
+ }
+
+ private boolean hasProgressbar(Control control) {
+ final Object hasProgressbar = control.getData(FLAG_WITH_PROGRESSBAR);
+ return (hasProgressbar instanceof Boolean) ? (Boolean) hasProgressbar : true;
+ }
+
+ private class SkillAdapter extends AdapterImpl {
+ @Override
+ public void notifyChanged(Notification msg) {
+
+ if (msg.getNotifier() instanceof ISkill)
+ fUiUpdateThrottler.throttledExec();
+ }
+ }
}
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/StatsComposite.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/StatsComposite.java
new file mode 100644
index 0000000..66fdb0e
--- /dev/null
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/character/StatsComposite.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.skills.ui.views.character;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.skills.model.ISkill;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+public class StatsComposite extends Composite {
+
+ private static final int INDENTATION = 30;
+
+ private static int compareSkillsByName(ISkill arg0, ISkill arg1) {
+ return arg0.getName().compareTo(arg1.getName());
+ }
+
+ private static List<ISkill> getPrimarySkills(Collection<ISkill> skills) {
+ final List<ISkill> primarySkills = skills.stream().filter(s -> s.isBaseSkill()).collect(Collectors.toList());
+ Collections.sort(primarySkills, StatsComposite::compareSkillsByName);
+
+ return primarySkills;
+ }
+
+ private static List<ISkill> getSecondarySkills(Collection<ISkill> skills) {
+ final List<ISkill> secondarySkills = skills.stream().filter(s -> !s.isBaseSkill()).collect(Collectors.toList());
+ Collections.sort(secondarySkills, StatsComposite::compareSkillsByName);
+
+ return secondarySkills;
+ }
+
+ public StatsComposite(Composite parent, int style, ResourceManager resourceManager) {
+ super(parent, style);
+
+ setLayout(new GridLayout());
+
+ final SkillsComposite xp = new SkillsComposite(this, SWT.NONE, Arrays.asList(CharacterView.getUser().getExperience()), true);
+ xp.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.FILL).create());
+
+ addSeparator();
+
+ final Label lblPrimarySkills = new Label(this, SWT.NONE);
+ lblPrimarySkills.setText("Your Stats:");
+
+ final List<ISkill> primarySkills = getPrimarySkills(CharacterView.getUser().getSkills());
+ final SkillsComposite primary = new SkillsComposite(this, SWT.NONE, primarySkills, false);
+ primary.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).indent(INDENTATION, 0).create());
+
+ addSeparator();
+
+ final Label lblSecondarySkills = new Label(this, SWT.NONE);
+ lblSecondarySkills.setText("Your Skills:");
+
+ final List<ISkill> secondarySkills = getSecondarySkills(CharacterView.getUser().getSkills());
+ final SkillsComposite secondary = new SkillsComposite(this, SWT.NONE, secondarySkills, true);
+ secondary.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).indent(INDENTATION, 0).create());
+
+ final BadgesComposite badgesComposite = new BadgesComposite(this, SWT.H_SCROLL, resourceManager);
+ badgesComposite.setLayoutData(GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BOTTOM).grab(true, true).create());
+ }
+
+ private void addSeparator() {
+ final Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
+ separator.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.FILL).create());
+ }
+
+ public void setSkills(EList<ISkill> skills) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/journal/JournalView.java b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/journal/JournalView.java
index abde37d..3ba8243 100644
--- a/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/journal/JournalView.java
+++ b/plugins/org.eclipse.skills/src/org/eclipse/skills/ui/views/journal/JournalView.java
@@ -31,7 +31,6 @@
import org.eclipse.skills.model.IUser;
import org.eclipse.skills.model.IUserTask;
import org.eclipse.skills.service.ISkillService;
-import org.eclipse.skills.ui.views.character.CharacterSheet;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Image;
@@ -156,13 +155,6 @@
return composite;
}
- private Composite createDetailHeaderComposite(Composite parent, FormToolkit toolkit) {
- final Composite composite = toolkit.createComposite(parent);
- composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
-
- return composite;
- }
-
private java.util.List<IUserTask> getOpenTasks() {
final java.util.List<IUserTask> tasks = getUser().getUsertasks().stream().filter(t -> !t.isStarted()).collect(Collectors.toList());
@@ -195,8 +187,7 @@
if (skillService != null)
return skillService.getUser();
- // needed when used in development mode in SWT designer
- return CharacterSheet.createDummyUser();
+ return null;
}
@Override
diff --git a/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/DataStorageProxyTest.java b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/DataStorageProxyTest.java
deleted file mode 100644
index 5cb4a7c..0000000
--- a/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/DataStorageProxyTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2020 Christian Pontesegger and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Christian Pontesegger - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.skills.service;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.EOFException;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-public class DataStorageProxyTest {
-
- private static byte[] DEFAULT_DATA = "Default data".getBytes();
-
- private IDataStorage fBaseStorage;
- private DataStorageProxy fDataStorage;
-
- @BeforeEach
- public void setup() {
- fBaseStorage = mock(IDataStorage.class);
- fDataStorage = new DataStorageProxy(fBaseStorage);
- }
-
- @Test
- @DisplayName("constructor throws when baseStorage is null")
- public void throwsWhenBaseStorageIsNull() {
- assertThrows(IllegalArgumentException.class, () -> new DataStorageProxy(null));
- }
-
- @Test
- @DisplayName("getStorage() returns baseStorage")
- public void getStorage() {
- assertEquals(fBaseStorage, fDataStorage.getStorage());
- }
-
- @Test
- @DisplayName("hasResource() == true when resource exists")
- public void hasResourceIsTrueWhenResourceExists() {
- when(fBaseStorage.hasResource(any())).thenReturn(true);
-
- assertTrue(fDataStorage.hasResource("any"));
- }
-
- @Test
- @DisplayName("hasResource() == false when resource does not exist")
- public void hasResourceIsFalseWhenResourceDoesNotExist() {
- when(fBaseStorage.hasResource(any())).thenReturn(false);
-
- assertFalse(fDataStorage.hasResource("any"));
- }
-
- @Test
- @DisplayName("loadResource() throws when resource does not exist")
- public void loadResourceThrowsWhenResourceDoesNotExist() {
- when(fBaseStorage.hasResource(any())).thenReturn(false);
-
- assertThrows(FileNotFoundException.class, () -> fDataStorage.loadResource("any"));
- }
-
- @Test
- @DisplayName("loadResource() returns data when resource exists")
- public void loadResourceReturnsDataWhenResourceExists() throws IOException {
- when(fBaseStorage.hasResource(any())).thenReturn(true);
- when(fBaseStorage.loadResource(any())).thenReturn(DEFAULT_DATA);
-
- assertArrayEquals(DEFAULT_DATA, fDataStorage.loadResource("any"));
- }
-
- @Test
- @DisplayName("loadResource() throws when base storage throws")
- public void loadResourceThrowsWhenBaseStorageThrows() throws IOException {
- when(fBaseStorage.hasResource(any())).thenReturn(true);
- when(fBaseStorage.loadResource(any())).thenThrow(new EOFException());
-
- assertThrows(EOFException.class, () -> fDataStorage.loadResource("any"));
- }
-
- @Test
- @DisplayName("hasResource() == true after storeResource()")
- public void hasResourceIsTrueAfterStoreResource() throws IOException {
- when(fBaseStorage.hasResource(any())).thenReturn(false).thenReturn(true);
-
- assertFalse(fDataStorage.hasResource("any"));
- fDataStorage.storeResource("any", DEFAULT_DATA);
- assertTrue(fDataStorage.hasResource("any"));
-
- verify(fBaseStorage, times(1)).storeResource(any(), any());
- }
-
- @Test
- @DisplayName("loadResource() returns storeResource() data")
- public void loadResourceReturnsStoreResourceData() throws IOException {
- when(fBaseStorage.hasResource(any())).thenReturn(true);
- when(fBaseStorage.loadResource(any())).thenReturn(DEFAULT_DATA);
-
- fDataStorage.storeResource("any", DEFAULT_DATA);
- assertArrayEquals(DEFAULT_DATA, fDataStorage.loadResource("any"));
-
- verify(fBaseStorage, times(1)).storeResource(any(), any());
- }
-
- @Test
- @DisplayName("storeResource() throws when base storage throws")
- public void storeResourceThrowsWhenBaseStorageThrows() throws IOException {
- doThrow(new EOFException()).when(fBaseStorage).storeResource(any(), any());
-
- assertThrows(EOFException.class, () -> fDataStorage.storeResource("any", DEFAULT_DATA));
- }
-
- @Test
- @DisplayName("setStorage() throws when baseStorage == null")
- public void setStorageThrowsOnNullParameter() {
- assertThrows(IllegalArgumentException.class, () -> fDataStorage.setStorage(null));
- }
-
- @Test
- @DisplayName("setStorage() allows to replace storage")
- public void setStorageSetsTheStorage() {
- when(fBaseStorage.hasResource(any())).thenReturn(true);
-
- final IDataStorage newStorage = mock(IDataStorage.class);
- when(newStorage.hasResource(any())).thenReturn(false);
-
- assertTrue(fDataStorage.hasResource("any"));
-
- fDataStorage.setStorage(newStorage);
- assertEquals(newStorage, fDataStorage.getStorage());
- assertFalse(fDataStorage.hasResource("any"));
- }
-}
diff --git a/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/UserStorageTest.java b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/UserStorageTest.java
index 629289a..2ea8c61 100644
--- a/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/UserStorageTest.java
+++ b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/UserStorageTest.java
@@ -30,6 +30,7 @@
import org.eclipse.skills.model.IUser;
import org.eclipse.skills.model.IUserTask;
+import org.eclipse.skills.service.storage.IDataStorage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
diff --git a/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/AbstractStorageTest.java b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/AbstractStorageTest.java
new file mode 100644
index 0000000..6e9b7ee
--- /dev/null
+++ b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/AbstractStorageTest.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.skills.service.storage;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public abstract class AbstractStorageTest {
+
+ private static final String UNKNOWN_FILE = "doesNotExist";
+ private static final String DEFAULT_FILE = "defaultFile";
+ public static final byte[] DEFAULT_CONTENT = "Lorem ipsum dolorem".getBytes();
+
+ private static byte[] readInputStream(InputStream input) throws IOException {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ final byte[] buffer = new byte[1024];
+ int bytesRead = input.read(buffer);
+ while (bytesRead > 0) {
+ out.write(buffer, 0, bytesRead);
+ bytesRead = input.read(buffer);
+ }
+
+ return out.toByteArray();
+ }
+
+ private IDataStorage fDataStorage;
+
+ @BeforeEach
+ public void setup() {
+ fDataStorage = createStorage();
+ }
+
+ public IDataStorage getDataStorage() {
+ return fDataStorage;
+ }
+
+ /**
+ * Create an instance of the storage under test.
+ *
+ * @return storage under test
+ */
+ protected abstract IDataStorage createStorage();
+
+ @Test
+ @DisplayName("hasResource() == false when file does not exist")
+ public void hasResourceFalseWhenFileDoesNotExist() {
+ assertFalse(fDataStorage.hasResource(UNKNOWN_FILE));
+ }
+
+ @Test
+ @DisplayName("hasResource() == true when file exists")
+ public void hasResourceTrueWhenFileExists() throws IOException {
+
+ fDataStorage.storeResource(DEFAULT_FILE, DEFAULT_CONTENT);
+
+ assertTrue(fDataStorage.hasResource(DEFAULT_FILE));
+ }
+
+ @Test
+ @DisplayName("loadResource() throws when file does not exist")
+ public void loadResourceThrowsWhenFileDoesNotExist() {
+ assertThrows(IOException.class, () -> fDataStorage.loadResource(UNKNOWN_FILE));
+ }
+
+ @Test
+ @DisplayName("loadResource() returns file content when file exists")
+ public void loadResourceReturnsFileContent() throws IOException {
+ fDataStorage.storeResource(DEFAULT_FILE, DEFAULT_CONTENT);
+
+ assertArrayEquals(DEFAULT_CONTENT, fDataStorage.loadResource(DEFAULT_FILE));
+ }
+
+ @Test
+ @DisplayName("openResource() throws when file does not exist")
+ public void openResourceThrowsWhenFileDoesNotExist() {
+ assertThrows(IOException.class, () -> fDataStorage.openResource(UNKNOWN_FILE));
+ }
+
+ @Test
+ @DisplayName("openResource() returns file content when file exists")
+ public void openResourceReturnsFileContent() throws IOException {
+ fDataStorage.storeResource(DEFAULT_FILE, DEFAULT_CONTENT);
+
+ assertArrayEquals(DEFAULT_CONTENT, readInputStream(fDataStorage.openResource(DEFAULT_FILE)));
+ }
+
+ @Test
+ @DisplayName("stored resource can be reloaded")
+ public void storedResourceCanBeReloaded() throws IOException {
+ final String content = new String(DEFAULT_CONTENT) + System.currentTimeMillis();
+ fDataStorage.storeResource(DEFAULT_FILE, content.getBytes());
+
+ assertArrayEquals(content.getBytes(), fDataStorage.loadResource(DEFAULT_FILE));
+ }
+
+ @Test
+ @DisplayName("hasResource() == true after storeResource()")
+ public void hasResourceIsTrueAfterStoreResource() throws IOException {
+ final String fileName = Long.toString(System.currentTimeMillis());
+
+ assertFalse(getDataStorage().hasResource(fileName));
+ getDataStorage().storeResource(fileName, DEFAULT_CONTENT);
+ assertTrue(getDataStorage().hasResource(fileName));
+ }
+}
diff --git a/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/DataStorageProxyTest.java b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/DataStorageProxyTest.java
new file mode 100644
index 0000000..d042adc
--- /dev/null
+++ b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/DataStorageProxyTest.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.skills.service.storage;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public class DataStorageProxyTest extends AbstractStorageTest {
+
+ private IDataStorage fBaseStorage;
+
+ @Override
+ protected IDataStorage createStorage() {
+ fBaseStorage = mock(IDataStorage.class);
+ return new DataStorageProxy(fBaseStorage);
+ }
+
+ @Override
+ public DataStorageProxy getDataStorage() {
+ return (DataStorageProxy) super.getDataStorage();
+ }
+
+ @Test
+ @DisplayName("constructor throws when baseStorage is null")
+ public void throwsWhenBaseStorageIsNull() {
+ assertThrows(IllegalArgumentException.class, () -> new DataStorageProxy(null));
+ }
+
+ @Test
+ @DisplayName("getStorage() returns baseStorage")
+ public void getStorage() {
+ assertEquals(fBaseStorage, getDataStorage().getStorage());
+ }
+
+ @Override
+ @Test
+ @DisplayName("hasResource() == false when file does not exist")
+ public void hasResourceFalseWhenFileDoesNotExist() {
+ when(fBaseStorage.hasResource(any())).thenReturn(false);
+
+ super.hasResourceFalseWhenFileDoesNotExist();
+ }
+
+ @Override
+ @Test
+ @DisplayName("hasResource() == true when file exists")
+ public void hasResourceTrueWhenFileExists() throws IOException {
+ when(fBaseStorage.hasResource(any())).thenReturn(true);
+
+ super.hasResourceTrueWhenFileExists();
+ }
+
+ @Override
+ @Test
+ @DisplayName("loadResource() throws when file does not exist")
+ public void loadResourceThrowsWhenFileDoesNotExist() {
+ when(fBaseStorage.hasResource(any())).thenReturn(false);
+
+ super.loadResourceThrowsWhenFileDoesNotExist();
+ }
+
+ @Override
+ @Test
+ @DisplayName("loadResource() returns file content when file exists")
+ public void loadResourceReturnsFileContent() throws IOException {
+ when(fBaseStorage.hasResource(any())).thenReturn(true);
+ when(fBaseStorage.loadResource(any())).thenReturn(DEFAULT_CONTENT);
+
+ super.loadResourceReturnsFileContent();
+ }
+
+ @Test
+ @DisplayName("loadResource() throws when base storage throws")
+ public void loadResourceThrowsWhenBaseStorageThrows() throws IOException {
+ when(fBaseStorage.hasResource(any())).thenReturn(true);
+ when(fBaseStorage.loadResource(any())).thenThrow(new EOFException());
+
+ assertThrows(EOFException.class, () -> getDataStorage().loadResource("any"));
+ }
+
+ @Override
+ @Test
+ @DisplayName("openResource() throws when file does not exist")
+ public void openResourceThrowsWhenFileDoesNotExist() {
+ when(fBaseStorage.hasResource(any())).thenReturn(false);
+
+ super.openResourceThrowsWhenFileDoesNotExist();
+ }
+
+ @Override
+ @Test
+ @DisplayName("openResource() returns file content when file exists")
+ public void openResourceReturnsFileContent() throws IOException {
+ when(fBaseStorage.hasResource(any())).thenReturn(true);
+ when(fBaseStorage.openResource(any())).thenReturn(new ByteArrayInputStream(DEFAULT_CONTENT));
+
+ super.openResourceReturnsFileContent();
+ }
+
+ @Test
+ @DisplayName("openResource() throws when base storage throws")
+ public void openResourceThrowsWhenBaseStorageThrows() throws IOException {
+ when(fBaseStorage.hasResource(any())).thenReturn(true);
+ when(fBaseStorage.openResource(any())).thenThrow(new EOFException());
+
+ assertThrows(EOFException.class, () -> getDataStorage().openResource("any"));
+ }
+
+ @Override
+ @Test
+ @DisplayName("stored resource can be reloaded")
+ public void storedResourceCanBeReloaded() throws IOException {
+ when(fBaseStorage.hasResource(any())).thenReturn(true);
+ when(fBaseStorage.loadResource(any())).thenReturn(DEFAULT_CONTENT);
+
+ getDataStorage().storeResource("any", DEFAULT_CONTENT);
+ assertArrayEquals(DEFAULT_CONTENT, getDataStorage().loadResource("any"));
+
+ verify(fBaseStorage, times(1)).storeResource(any(), any());
+ }
+
+ @Override
+ @Test
+ @DisplayName("hasResource() == true after storeResource()")
+ public void hasResourceIsTrueAfterStoreResource() throws IOException {
+ when(fBaseStorage.hasResource(any())).thenReturn(false).thenReturn(true);
+
+ super.hasResourceIsTrueAfterStoreResource();
+
+ verify(fBaseStorage, times(1)).storeResource(any(), any());
+ }
+
+ @Test
+ @DisplayName("storeResource() throws when base storage throws")
+ public void storeResourceThrowsWhenBaseStorageThrows() throws IOException {
+ doThrow(new EOFException()).when(fBaseStorage).storeResource(any(), any());
+
+ assertThrows(EOFException.class, () -> getDataStorage().storeResource("any", DEFAULT_CONTENT));
+ }
+
+ @Test
+ @DisplayName("setStorage() throws when baseStorage == null")
+ public void setStorageThrowsOnNullParameter() {
+ assertThrows(IllegalArgumentException.class, () -> getDataStorage().setStorage(null));
+ }
+
+ @Test
+ @DisplayName("setStorage() allows to replace storage")
+ public void setStorageSetsTheStorage() {
+ when(fBaseStorage.hasResource(any())).thenReturn(true);
+
+ final IDataStorage newStorage = mock(IDataStorage.class);
+ when(newStorage.hasResource(any())).thenReturn(false);
+
+ assertTrue(getDataStorage().hasResource("any"));
+
+ getDataStorage().setStorage(newStorage);
+ assertEquals(newStorage, getDataStorage().getStorage());
+ assertFalse(getDataStorage().hasResource("any"));
+ }
+}
diff --git a/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/WorkspaceDataStorageTest.java b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/WorkspaceDataStorageTest.java
new file mode 100644
index 0000000..5d55ca2
--- /dev/null
+++ b/tests/org.eclipse.skills.test/src/org/eclipse/skills/service/storage/WorkspaceDataStorageTest.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Christian Pontesegger and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian Pontesegger - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.skills.service.storage;
+
+public class WorkspaceDataStorageTest extends AbstractStorageTest {
+
+ @Override
+ protected IDataStorage createStorage() {
+ return new WorkspaceDataStorage();
+ }
+
+}