Skip to content

Commit 39a00d1

Browse files
Dm 33/add and adapt necessary dtos (#265)
* Adapt ProductId with FromSTring method and implement ProductTypeFactory for DM-33
1 parent 9091fbb commit 39a00d1

File tree

5 files changed

+195
-8
lines changed

5 files changed

+195
-8
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.
99

1010
**Added**
1111

12+
* Added ProductTypeFactory ``life.qbic.datamodel.dtos.business.services.ProductTypeFactory``
13+
* ProductId now provides 'From' method to be created via String representation
14+
1215
**Fixed**
1316

1417
**Dependencies**

src/main/groovy/life/qbic/datamodel/dtos/business/ProductId.groovy

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package life.qbic.datamodel.dtos.business
22

33
import groovy.transform.EqualsAndHashCode
4+
import life.qbic.datamodel.dtos.business.services.ProductType
5+
import life.qbic.datamodel.dtos.business.services.ProductTypeFactory
46

57
/**
68
* A DTO describing Product Identifiers
@@ -113,6 +115,40 @@ class ProductId implements Comparable<ProductId>{
113115
return type
114116
}
115117

118+
/**
119+
* Returns a ProductId from a given String representation
120+
*
121+
* Expects a ProductIdString with the Format P_N
122+
* P being the one of the abbreviation values stored in {@link ProductType} enum
123+
* N being an Integer Number
124+
*
125+
* @param String representation of a productId
126+
* @return ProductId containing type and uniqueNumber of String representation
127+
*/
128+
static ProductId from(String productId) {
129+
if (!productId.contains("_")) {
130+
throw new IllegalArgumentException("Not a valid product identifier.")
131+
}
132+
def splitId = productId.split("_")
133+
String productTypeString
134+
String runningNumberString
135+
Long runningNumber
136+
try {
137+
ProductTypeFactory productTypeFactory = new ProductTypeFactory()
138+
productTypeString = splitId[0].trim()
139+
runningNumberString = splitId[1].trim()
140+
runningNumber = Long.parseUnsignedLong(runningNumberString)
141+
ProductType productType = productTypeFactory.getForString(productTypeString)
142+
}
143+
catch (NumberFormatException numberFormatException) {
144+
throw new NumberFormatException("Provided productId does not have a valid uniqueID")
145+
}
146+
catch (IllegalArgumentException illegalArgumentException) {
147+
throw new IllegalArgumentException("ProductId does not have a valid ProductType")
148+
}
149+
return new Builder(productTypeString, runningNumber).build()
150+
}
151+
116152
/**
117153
* Returns a String representation in the format:
118154
*
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package life.qbic.datamodel.dtos.business.services
2+
3+
import life.qbic.datamodel.dtos.EnumFactory
4+
5+
/**
6+
* This class provides functionality for enum key retrieval
7+
*
8+
* This class retrieves the corresponding ProductType for a given String
9+
*
10+
* @see life.qbic.datamodel.dtos.business.services.ProductType
11+
* @since: 2.14.0
12+
*/
13+
class ProductTypeFactory extends EnumFactory<ProductType>{
14+
15+
/**
16+
* This method returns the enum with the provided String value.
17+
*
18+
* @throws IllegalArgumentException in case the String could not be mapped
19+
* @param value the String corresponding to a key of the enum
20+
* @return the enum key for the provided string value
21+
*/
22+
@Override
23+
ProductType getForString(String value) {
24+
ProductType desiredKey
25+
desiredKey = ProductType.values().find { (it.value == value.trim()) }
26+
if (!desiredKey) {
27+
throw new IllegalArgumentException("Invalid value '$value' for ${ProductType.getSimpleName()}")
28+
}
29+
return desiredKey
30+
}
31+
}

src/test/groovy/life/qbic/datamodel/dtos/business/ProductIdSpec.groovy

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,84 @@ class ProductIdSpec extends Specification {
120120
result == expectedResult
121121
122122
where:
123-
x | y | expectedResult
124-
new ProductId.Builder("A",1).build() | new ProductId.Builder("B",1).build() | -1
125-
new ProductId.Builder("B",1).build() | new ProductId.Builder("A",1).build() | 1
126-
new ProductId.Builder("A",1).build() | new ProductId.Builder("A",1).build() | 0
127-
new ProductId.Builder("A",1).build() | new ProductId.Builder("A",42).build() | -1
128-
new ProductId.Builder("A",42).build() | new ProductId.Builder("A",1).build() | 1
129-
new ProductId.Builder("A",1).build() | new ProductId.Builder("B",0).build() | -1
130-
new ProductId.Builder("Z",42).build() | new ProductId.Builder("A",100).build() | 1
123+
x | y | expectedResult
124+
new ProductId.Builder("A", 1).build() | new ProductId.Builder("B", 1).build() | -1
125+
new ProductId.Builder("B", 1).build() | new ProductId.Builder("A", 1).build() | 1
126+
new ProductId.Builder("A", 1).build() | new ProductId.Builder("A", 1).build() | 0
127+
new ProductId.Builder("A", 1).build() | new ProductId.Builder("A", 42).build() | -1
128+
new ProductId.Builder("A", 42).build() | new ProductId.Builder("A", 1).build() | 1
129+
new ProductId.Builder("A", 1).build() | new ProductId.Builder("B", 0).build() | -1
130+
new ProductId.Builder("Z", 42).build() | new ProductId.Builder("A", 100).build() | 1
131131
132132
}
133133
134+
def "Valid ProductId String can be converted to ProductId"() {
135+
when:
136+
ProductId productId = ProductId.from(validProductIdString)
137+
then:
138+
validProductId == productId
139+
140+
where:
141+
validProductIdString | validProductId
142+
"SE_1" | new ProductId.Builder("SE", 1).build()
143+
"PM_2" | new ProductId.Builder("PM", 2).build()
144+
"PB_3" | new ProductId.Builder("PB", 3).build()
145+
"SB_4" | new ProductId.Builder("SB", 4).build()
146+
"DS_5" | new ProductId.Builder("DS", 5).build()
147+
"PR_6" | new ProductId.Builder("PR", 6).build()
148+
"ME_7" | new ProductId.Builder("ME", 7).build()
149+
"EXT_8" | new ProductId.Builder("EXT", 8).build()
150+
}
151+
152+
def "ProductId String with invalid number will return NumberFormatException"() {
153+
when:
154+
ProductId.from(inValidProductIdString)
155+
then:
156+
thrown(NumberFormatException)
157+
where:
158+
inValidProductIdString | _
159+
"SE_1.5" | _
160+
"PM_Z" | _
161+
"PB_ARG" | _
162+
"SB_1,4" | _
163+
"DS_1,A" | _
164+
"PR_A_5" | _
165+
"ME_A-0" | _
166+
"EXT_D/0" | _
167+
}
168+
169+
def "ProductId String with invalid productType will return IllegalArgumentException"() {
170+
when:
171+
ProductId.from(inValidProductIdString)
172+
then:
173+
thrown(IllegalArgumentException)
174+
where:
175+
inValidProductIdString | _
176+
"Dane_1" | _
177+
"Mary_2" | _
178+
"Fred_3" | _
179+
"A:P_4" | _
180+
"101_5" | _
181+
"Wat_6" | _
182+
"Decibel_7" | _
183+
"Why_8" | _
184+
}
185+
186+
def "ProductId String with invalid Format will return IllegalArgumentException"() {
187+
when:
188+
ProductId.from(inValidProductIdString)
189+
then:
190+
thrown(IllegalArgumentException)
191+
where:
192+
inValidProductIdString | _
193+
"SE1" | _
194+
"PM2" | _
195+
"PB3" | _
196+
"SB4" | _
197+
"DS5" | _
198+
"PR&6" | _
199+
"ME-7" | _
200+
"EXT/8" | _
201+
}
134202
135203
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package life.qbic.datamodel.dtos.business.services
2+
3+
import spock.lang.Specification
4+
5+
/**
6+
* <h1>Tests the ProductTypeFactory</h1>
7+
*
8+
* @since 2.14.0
9+
* @see ProductTypeFactory
10+
*/
11+
class ProductTypeFactorySpec extends Specification {
12+
def "GetForString works for all values"() {
13+
setup:
14+
ProductTypeFactory factory = new ProductTypeFactory()
15+
when:
16+
ProductType result = factory.getForString(testValue)
17+
then:
18+
result == expectedValue
19+
where:
20+
testValue | expectedValue
21+
"SE" | ProductType.SEQUENCING
22+
"PM" | ProductType.PROJECT_MANAGEMENT
23+
"PB" | ProductType.PRIMARY_BIOINFO
24+
"SB" | ProductType.SECONDARY_BIOINFO
25+
"DS" | ProductType.DATA_STORAGE
26+
"PR" | ProductType.PROTEOMIC
27+
"ME" | ProductType.METABOLOMIC
28+
"EXT" | ProductType.EXTERNAL_SERVICE
29+
}
30+
31+
def "GetForString throws IllegalArgument on unknown String"() {
32+
setup:
33+
ProductTypeFactory factory = new ProductTypeFactory()
34+
when:
35+
ProductType result = factory.getForString(testValue)
36+
then:
37+
thrown IllegalArgumentException
38+
where:
39+
testValue | expectedValue
40+
"se" | ProductType.SEQUENCING
41+
"pm" | ProductType.PROJECT_MANAGEMENT
42+
"pb" | ProductType.PRIMARY_BIOINFO
43+
"sb" | ProductType.SECONDARY_BIOINFO
44+
"ds" | ProductType.DATA_STORAGE
45+
"pr" | ProductType.PROTEOMIC
46+
"me" | ProductType.METABOLOMIC
47+
"ext" | ProductType.EXTERNAL_SERVICE
48+
}
49+
}

0 commit comments

Comments
 (0)