]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
should return instead of break.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / entity / Token.java
CommitLineData
878ddf1f 1/** @file\r
2 Token class.\r
3\r
4 This module contains all classes releted to PCD token.\r
5 \r
6Copyright (c) 2006, Intel Corporation\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11 \r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/ \r
16package org.tianocore.build.pcd.entity;\r
17\r
6f7e61a0 18import java.math.BigInteger;\r
878ddf1f 19import java.util.ArrayList;\r
6f7e61a0 20import java.util.HashMap;\r
878ddf1f 21import java.util.List;\r
8840ad58 22import java.util.Map;\r
6f7e61a0 23import java.util.UUID;\r
878ddf1f 24\r
25import org.tianocore.build.pcd.action.ActionMessage;\r
8840ad58 26import org.tianocore.build.pcd.exception.EntityException;\r
878ddf1f 27\r
28/** This class is to descript a PCD token object. The information of a token mainly \r
29 comes from MSA, SPD and setting produced by platform developer. \r
30**/\r
31public class Token {\r
32 ///\r
33 /// Enumeration macro defintion for PCD type.\r
34 /// BUGBUG: Not use upcase charater is to facility for reading. It may be changed\r
35 /// in coding review.\r
36 public enum PCD_TYPE {FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODULE, DYNAMIC, \r
37 DYNAMIC_EX, UNKNOWN}\r
38\r
39 ///\r
40 /// Enumeration macro definition for datum type. All type mainly comes from ProcessBind.h.\r
41 /// Wizard maybe expand this type as "int, unsigned int, short, unsigned short etc" in \r
42 /// prompt dialog.\r
43 ///\r
44 public enum DATUM_TYPE {UINT8, UINT16, UINT32, UINT64, BOOLEAN, POINTER, UNKNOWN}\r
45\r
46 ///\r
47 /// Enumeration macor defintion for usage of PCD\r
48 ///\r
49 public enum PCD_USAGE {ALWAYS_PRODUCED, ALWAYS_CONSUMED, SOMETIMES_PRODUCED,\r
50 SOMETIMES_CONSUMED, UNKNOWN}\r
51\r
52 ///\r
53 /// cName is to identify a PCD entry and will be used for generating autogen.h/autogen.c.\r
54 /// cName will be defined in MSA, SPD and FPD, can be regarded as primary key with token space guid.\r
55 ///\r
56 public String cName;\r
57\r
58 ///\r
59 /// Token space name is the guid defined by token itself in package or module level. This\r
60 /// name mainly for DynamicEx type. For other PCD type token, his token space name is the \r
61 /// assignedtokenSpaceName as follows.\r
62 /// tokenSpaceName is defined in MSA, SPD, FPD, can be regarded as primary key with cName.\r
63 ///\r
64 public UUID tokenSpaceName;\r
65\r
66 ///\r
67 /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in\r
68 /// platform token space.\r
69 /// tokenNumber is defined in SPD, FPD.\r
70 ///\r
71 public int tokenNumber;\r
72\r
878ddf1f 73 ///\r
6ff7a41c 74 /// All supported PCD type, this value can be retrieved from SPD\r
75 /// Currently, only record all PCD type for this token in FPD file.\r
76 /// \r
77 public List<PCD_TYPE> supportedPcdType;\r
78\r
878ddf1f 79 ///\r
6ff7a41c 80 /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD\r
81 /// is true.\r
82 /// \r
83 public boolean isDynamicPCD;\r
878ddf1f 84\r
878ddf1f 85 ///\r
86 /// datumSize is to descript the fix size or max size for this token. \r
87 /// datumSize is defined in SPD.\r
88 ///\r
89 public int datumSize;\r
90\r
91 ///\r
92 /// datum type is to descript what type can be expressed by a PCD token.\r
6ff7a41c 93 /// For same PCD used in different module, the datum type should be unique.\r
94 /// So it belong memeber to Token class.\r
878ddf1f 95 ///\r
96 public DATUM_TYPE datumType;\r
97\r
878ddf1f 98 ///\r
99 /// skuData contains all value for SkuNumber of token.\r
6ff7a41c 100 /// This field is for Dynamic or DynamicEx type PCD, \r
878ddf1f 101 ///\r
102 public List<SkuInstance> skuData;\r
103\r
878ddf1f 104 ///\r
105 /// consumers array record all module private information who consume this PCD token.\r
106 ///\r
8840ad58 107 public Map<String, UsageInstance> consumers;\r
878ddf1f 108\r
8840ad58 109 public Token(String cName, UUID tokenSpaceName) {\r
878ddf1f 110 UUID nullUUID = new UUID(0, 0);\r
111\r
112 this.cName = cName;\r
8840ad58 113 this.tokenSpaceName = (tokenSpaceName == null) ? nullUUID : tokenSpaceName;\r
878ddf1f 114 this.tokenNumber = 0;\r
878ddf1f 115 this.datumType = DATUM_TYPE.UNKNOWN;\r
116 this.datumSize = -1;\r
878ddf1f 117 this.skuData = new ArrayList<SkuInstance>();\r
878ddf1f 118\r
8840ad58 119 this.consumers = new HashMap<String, UsageInstance>();\r
6ff7a41c 120 this.supportedPcdType = new ArrayList<PCD_TYPE>();\r
121 }\r
122\r
123 /**\r
124 updateSupportPcdType\r
125 \r
126 SupportPcdType should be gotten from SPD file actually, but now it just\r
127 record all PCD type for this token in FPD file.\r
128 \r
129 @param pcdType new PCD type found in FPD file for this token.\r
130 **/\r
131 public void updateSupportPcdType(PCD_TYPE pcdType) {\r
132 int index = 0;\r
133 boolean found = false;\r
134 for (index = 0; index < this.supportedPcdType.size(); index ++) {\r
135 if (this.supportedPcdType.get(index) == pcdType) {\r
136 found = true;\r
137 break;\r
138 }\r
139 }\r
140 if (!found) {\r
141 this.supportedPcdType.add(pcdType);\r
142 }\r
143 }\r
144\r
145 /**\r
146 Judge whether pcdType is belong to dynamic type. Dynamic type includes\r
147 DYNAMIC and DYNAMIC_EX.\r
148 \r
149 @param pcdType\r
150 \r
151 @return boolean\r
152 */\r
153 public static boolean isDynamic(PCD_TYPE pcdType) {\r
154 if ((pcdType == PCD_TYPE.DYNAMIC ) ||\r
155 (pcdType == PCD_TYPE.DYNAMIC_EX)) {\r
156 return true;\r
157 }\r
158\r
159 return false;\r
878ddf1f 160 }\r
161\r
162 /**\r
163 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database\r
164 \r
165 @param cName Token name.\r
166 @param tokenSpaceName The token space guid defined in MSA or SPD\r
167 @param platformtokenSpaceName The token space guid for current platform token space,\r
168 \r
169 @return primary key for this token in token database.\r
170 **/\r
8840ad58 171 public static String getPrimaryKeyString(String cName, UUID tokenSpaceName) {\r
878ddf1f 172 UUID nullUUID = new UUID(0, 0);\r
173\r
8840ad58 174 if (tokenSpaceName == null) {\r
175 return cName + "_" + nullUUID.toString().replace('-', '_');\r
878ddf1f 176 } else {\r
8840ad58 177 return cName + "_" + tokenSpaceName.toString().replace('-', '_');\r
878ddf1f 178 }\r
179 }\r
180\r
6ff7a41c 181 /**\r
182 If skudata list contains more than one data, then Sku mechanism is enable.\r
183 \r
184 @return boolean\r
185 */\r
186 public boolean isSkuEnable() {\r
187 if (this.skuData.size() > 1) {\r
188 return true;\r
189 }\r
190 return false;\r
191 }\r
192\r
8840ad58 193 /**\r
194 Get the token primary key in token database.\r
195 \r
196 @return String\r
197 */\r
32648c62 198 public String getPrimaryKeyString () {\r
8840ad58 199 return Token.getPrimaryKeyString(cName, tokenSpaceName);\r
32648c62 200 }\r
99d2c3c4 201\r
878ddf1f 202 /**\r
203 Judge datumType is valid\r
204 \r
205 @param type The datumType want to be judged.\r
206 \r
207 @retval TRUE - The type is valid.\r
208 @retval FALSE - The type is invalid.\r
209 **/\r
210 public static boolean isValiddatumType(DATUM_TYPE type) {\r
211 if ((type.ordinal() < DATUM_TYPE.UINT8.ordinal() ) || \r
212 (type.ordinal() > DATUM_TYPE.POINTER.ordinal())) {\r
213 return false;\r
214 }\r
215 return true;\r
216 }\r
217\r
218 /**\r
219 Judge pcdType is valid\r
220 \r
221 @param type The PCdType want to be judged.\r
222 \r
223 @retval TRUE - The type is valid.\r
224 @retval FALSE - The type is invalid.\r
225 **/\r
226 public static boolean isValidpcdType(PCD_TYPE type) {\r
227 if ((type.ordinal() < PCD_TYPE.FEATURE_FLAG.ordinal() ) || \r
228 (type.ordinal() > PCD_TYPE.DYNAMIC_EX.ordinal())) {\r
229 return false;\r
230 }\r
231 return true;\r
232 }\r
233\r
234 /**\r
235 Add an usage instance for token\r
236 \r
237 @param usageInstance The usage instance\r
238 \r
239 @retval TRUE - Success to add usage instance.\r
240 @retval FALSE - Fail to add usage instance\r
241 **/\r
8840ad58 242 public boolean addUsageInstance(UsageInstance usageInstance) \r
243 throws EntityException {\r
244 String exceptionStr;\r
245\r
246 if (isUsageInstanceExist(usageInstance.moduleName,\r
247 usageInstance.moduleGUID,\r
248 usageInstance.packageName,\r
249 usageInstance.packageGUID,\r
250 usageInstance.arch,\r
251 usageInstance.version)) {\r
252 exceptionStr = String.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+\r
253 "in modules PcdPeim in <ModuleSA> to make sure no duplicated definitions!",\r
254 usageInstance.parentToken.cName,\r
255 usageInstance.moduleName);\r
256 throw new EntityException(exceptionStr);\r
878ddf1f 257 }\r
258\r
8840ad58 259 consumers.put(usageInstance.getPrimaryKey(), usageInstance);\r
878ddf1f 260 return true;\r
261 }\r
262\r
263 /**\r
8840ad58 264 Judge whether exist an usage instance for this token\r
265 \r
266 @param moduleName the name of module\r
267 @param moduleGuid the GUID name of modules\r
268 @param packageName the name of package contains this module\r
269 @param packageGuid the GUID name of package contains this module\r
270 @param arch the architecture string\r
271 @param version the version string\r
272 \r
273 @return boolean whether exist an usage instance for this token.\r
274 */\r
275 public boolean isUsageInstanceExist(String moduleName,\r
276 UUID moduleGuid,\r
277 String packageName,\r
278 UUID packageGuid,\r
279 String arch,\r
280 String version) {\r
281 String keyStr = UsageInstance.getPrimaryKey(moduleName, \r
282 moduleGuid, \r
283 packageName, \r
284 packageGuid, \r
285 arch, \r
286 version);\r
287 return (consumers.get(keyStr) != null);\r
878ddf1f 288 }\r
289\r
290 /**\r
291 Get the PCD_TYPE according to the string of PCD_TYPE\r
292 \r
293 @param pcdTypeStr The string of PCD_TYPE\r
294 \r
295 @return PCD_TYPE\r
296 **/\r
297 public static PCD_TYPE getpcdTypeFromString(String pcdTypeStr) {\r
298 if (pcdTypeStr == null) {\r
299 return PCD_TYPE.UNKNOWN;\r
300 }\r
301\r
302 if (pcdTypeStr.equalsIgnoreCase("FEATURE_FLAG")) {\r
303 return PCD_TYPE.FEATURE_FLAG;\r
304 } else if (pcdTypeStr.equalsIgnoreCase("FIXED_AT_BUILD")) {\r
305 return PCD_TYPE.FIXED_AT_BUILD;\r
306 } else if (pcdTypeStr.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {\r
307 return PCD_TYPE.PATCHABLE_IN_MODULE;\r
308 } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC")) {\r
309 return PCD_TYPE.DYNAMIC;\r
310 } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC_EX")) {\r
311 return PCD_TYPE.DYNAMIC_EX;\r
312 } else {\r
313 return PCD_TYPE.UNKNOWN;\r
314 }\r
315 }\r
316\r
317 /**\r
318 Get the string of given datumType. This string will be used for generating autogen files\r
319 \r
320 @param datumType Given datumType\r
321 \r
322 @return The string of datum type.\r
323 **/\r
324 public static String getStringOfdatumType(DATUM_TYPE datumType) {\r
325 switch (datumType) {\r
326 case UINT8:\r
327 return "UINT8";\r
328 case UINT16:\r
329 return "UINT16";\r
330 case UINT32:\r
331 return "UINT32";\r
332 case UINT64:\r
333 return "UINT64";\r
334 case POINTER:\r
335 return "POINTER";\r
336 case BOOLEAN:\r
337 return "BOOLEAN";\r
338 }\r
339 return "UNKNOWN";\r
340 }\r
341\r
342 /**\r
343 Get the datumType according to a string.\r
344 \r
345 @param datumTypeStr The string of datumType\r
346 \r
347 @return DATUM_TYPE\r
348 **/\r
349 public static DATUM_TYPE getdatumTypeFromString(String datumTypeStr) {\r
350 if (datumTypeStr.equalsIgnoreCase("UINT8")) {\r
351 return DATUM_TYPE.UINT8;\r
352 } else if (datumTypeStr.equalsIgnoreCase("UINT16")) {\r
353 return DATUM_TYPE.UINT16;\r
354 } else if (datumTypeStr.equalsIgnoreCase("UINT32")) {\r
355 return DATUM_TYPE.UINT32;\r
356 } else if (datumTypeStr.equalsIgnoreCase("UINT64")) {\r
357 return DATUM_TYPE.UINT64;\r
358 } else if (datumTypeStr.equalsIgnoreCase("VOID*")) {\r
359 return DATUM_TYPE.POINTER;\r
360 } else if (datumTypeStr.equalsIgnoreCase("BOOLEAN")) {\r
361 return DATUM_TYPE.BOOLEAN;\r
362 }\r
363 return DATUM_TYPE.UNKNOWN;\r
364 }\r
365\r
366 /**\r
367 Get string of given pcdType\r
368 \r
369 @param pcdType The given PcdType\r
370 \r
371 @return The string of PCD_TYPE.\r
372 **/\r
373 public static String getStringOfpcdType(PCD_TYPE pcdType) {\r
374 switch (pcdType) {\r
375 case FEATURE_FLAG:\r
376 return "FEATURE_FLAG";\r
377 case FIXED_AT_BUILD:\r
378 return "FIXED_AT_BUILD";\r
379 case PATCHABLE_IN_MODULE:\r
380 return "PATCHABLE_IN_MODULE";\r
381 case DYNAMIC:\r
382 return "DYNAMIC";\r
383 case DYNAMIC_EX:\r
384 return "DYNAMIC_EX";\r
385 }\r
386 return "UNKNOWN";\r
387 }\r
388\r
389 /**\r
390 Get the PCD_USAGE according to a string\r
391 \r
392 @param usageStr The string of PCD_USAGE\r
393 \r
394 @return The PCD_USAGE\r
395 **/\r
396 public static PCD_USAGE getUsageFromString(String usageStr) {\r
397 if (usageStr == null) {\r
398 return PCD_USAGE.UNKNOWN;\r
399 }\r
400\r
401 if (usageStr.equalsIgnoreCase("ALWAYS_PRODUCED")) {\r
402 return PCD_USAGE.ALWAYS_PRODUCED;\r
403 } else if (usageStr.equalsIgnoreCase("SOMETIMES_PRODUCED")) {\r
404 return PCD_USAGE.SOMETIMES_PRODUCED;\r
405 } else if (usageStr.equalsIgnoreCase("ALWAYS_CONSUMED")) {\r
406 return PCD_USAGE.ALWAYS_CONSUMED;\r
407 } else if (usageStr.equalsIgnoreCase("SOMETIMES_CONSUMED")) {\r
408 return PCD_USAGE.SOMETIMES_CONSUMED;\r
409 }\r
410\r
411 return PCD_USAGE.UNKNOWN;\r
412 }\r
413\r
414 /**\r
415 Get the string of given PCD_USAGE\r
416 \r
417 @param usage The given PCD_USAGE\r
418 \r
419 @return The string of PDC_USAGE.\r
420 **/\r
421 public static String getStringOfUsage(PCD_USAGE usage) {\r
422 switch (usage) {\r
423 case ALWAYS_PRODUCED:\r
424 return "ALWAYS_PRODUCED";\r
425 case ALWAYS_CONSUMED:\r
426 return "ALWAYS_CONSUMED";\r
427 case SOMETIMES_PRODUCED:\r
428 return "SOMETIMES_PRODUCED";\r
429 case SOMETIMES_CONSUMED:\r
430 return "SOMETIMES_CONSUMED";\r
431 }\r
432 return "UNKNOWN";\r
433 }\r
434\r
435 /**\r
436 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h\r
437 \r
438 @param datumType The given datumType\r
439\r
440 @return string of datum type for autogen.\r
441 **/\r
442 public static String GetAutogenDefinedatumTypeString(DATUM_TYPE datumType) {\r
443 switch (datumType) {\r
444 \r
445 case UINT8:\r
446 return "8";\r
447 case UINT16:\r
448 return "16";\r
449 case BOOLEAN:\r
450 return "BOOL";\r
451 case POINTER:\r
452 return "PTR";\r
453 case UINT32:\r
454 return "32";\r
455 case UINT64:\r
456 return "64";\r
457 default:\r
458 return null;\r
459 }\r
460 }\r
461\r
462 /**\r
463 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen\r
464 \r
465 @param datumType The given datumType\r
466\r
467 @return string of datum type.\r
468 **/\r
469 public static String getAutogendatumTypeString(DATUM_TYPE datumType) {\r
470 switch (datumType) {\r
471 case UINT8:\r
472 return "UINT8";\r
473 case UINT16:\r
474 return "UINT16";\r
475 case UINT32:\r
476 return "UINT32";\r
477 case UINT64:\r
478 return "UINT64";\r
479 case POINTER:\r
480 return "VOID*";\r
481 case BOOLEAN:\r
482 return "BOOLEAN";\r
483 }\r
484 return null;\r
485 }\r
486\r
487 /**\r
488 Get the datumType string for generating some MACROs in autogen file of Library\r
489 \r
490 @param datumType The given datumType\r
491\r
492 @return String of datum for genrating bit charater.\r
493 **/\r
494 public static String getAutogenLibrarydatumTypeString(DATUM_TYPE datumType) {\r
495 switch (datumType) {\r
496 case UINT8:\r
497 return "8";\r
498 case UINT16:\r
499 return "16";\r
500 case BOOLEAN:\r
501 return "Bool";\r
502 case POINTER:\r
503 return "Ptr";\r
504 case UINT32:\r
505 return "32";\r
506 case UINT64:\r
507 return "64";\r
508 default:\r
509 return null;\r
510 }\r
511 }\r
512\r
513 /**\r
514 UUID defined in Schems is object, this function is to tranlate this object \r
515 to UUID data.\r
516 \r
517 @param uuidObj The object comes from schema.\r
518 \r
519 @return The traslated UUID instance.\r
520 **/\r
521 public static UUID getGUIDFromSchemaObject(Object uuidObj) {\r
522 UUID uuid;\r
523 if (uuidObj.toString().equalsIgnoreCase("0")) {\r
524 uuid = new UUID(0,0);\r
525 } else {\r
526 uuid = UUID.fromString(uuidObj.toString());\r
527 }\r
528\r
529 return uuid;\r
530 }\r
99d2c3c4 531\r
6ff7a41c 532 public DynamicTokenValue getDefaultSku() {\r
533 DynamicTokenValue dynamicData;\r
534 int index;\r
535 for (index = 0; index < this.skuData.size(); index ++) {\r
536 if (skuData.get(index).id == 0) {\r
537 return skuData.get(index).value;\r
538 }\r
539 }\r
540\r
541 return null;\r
542 }\r
99d2c3c4 543 //\r
544 // BugBug: We need change this algorithm accordingly when schema is updated\r
545 // to support no default value.\r
546 //\r
547 public boolean hasDefaultValue () {\r
6ff7a41c 548 int value = 0;\r
549 boolean isInteger = true;\r
550 DynamicTokenValue dynamicValue = null;\r
551\r
552 if (this.isDynamicPCD) {\r
553 dynamicValue = getDefaultSku();\r
554 switch (dynamicValue.type) {\r
555 case HII_TYPE:\r
6f7e61a0 556 return !isValidNullValue(dynamicValue.hiiDefaultValue);\r
6ff7a41c 557 case VPD_TYPE:\r
558 return false;\r
6ff7a41c 559 case DEFAULT_TYPE:\r
6f7e61a0 560 return !isValidNullValue(dynamicValue.value);\r
561 }\r
562 }\r
563\r
564 return false;\r
565 }\r
6ff7a41c 566\r
6f7e61a0 567 public boolean isValidNullValue(String judgedValue) {\r
568 int intValue;\r
569 BigInteger bigIntValue;\r
570\r
571 switch (datumType) {\r
572 case UINT8:\r
573 case UINT16:\r
574 case UINT32:\r
575 intValue = Integer.decode(judgedValue);\r
576 if (intValue == 0) {\r
577 return true;\r
578 }\r
579 break;\r
580 case UINT64:\r
581 if (judgedValue.length() > 2){\r
582 if ((judgedValue.charAt(0) == '0') && \r
583 ((judgedValue.charAt(1) == 'x') ||\r
584 (judgedValue.charAt(1) == 'X'))) {\r
585 bigIntValue = new BigInteger(judgedValue.substring(2, judgedValue.length()), 16);\r
586 if (bigIntValue.bitCount() == 0) {\r
587 return true;\r
588 }\r
6ff7a41c 589 } else {\r
6f7e61a0 590 bigIntValue = new BigInteger(judgedValue);\r
591 if (bigIntValue.bitCount() == 0) {\r
592 return true;\r
593 }\r
594 }\r
595 } else {\r
596 bigIntValue = new BigInteger(judgedValue);\r
597 if (bigIntValue.bitCount() == 0) {\r
6ff7a41c 598 return true;\r
599 }\r
6f7e61a0 600 }\r
601 break;\r
602 case BOOLEAN:\r
603 if (judgedValue.equalsIgnoreCase("false")) {\r
604 return true;\r
605 }\r
606 break;\r
607 case POINTER:\r
608 if (judgedValue.equalsIgnoreCase("") ||\r
609 judgedValue.equalsIgnoreCase("\"\"") ||\r
610 judgedValue.equalsIgnoreCase("L\"\"") ||\r
611 (judgedValue.length() == 0) ||\r
612 judgedValue.equalsIgnoreCase("{}")) {\r
613 return true;\r
6ff7a41c 614 }\r
32648c62 615 }\r
6ff7a41c 616 return false;\r
99d2c3c4 617 }\r
618\r
32648c62 619 public boolean isStringType () {\r
6ff7a41c 620 String str = getDefaultSku().value;\r
99d2c3c4 621\r
6f7e61a0 622 //\r
623 // BUGBUG: need scott confirmation.\r
624 // \r
625 if (datumType == Token.DATUM_TYPE.POINTER) {\r
32648c62 626 return true;\r
627 }\r
99d2c3c4 628\r
32648c62 629 return false;\r
630 }\r
99d2c3c4 631\r
32648c62 632 public String getStringTypeString () { \r
6ff7a41c 633 return getDefaultSku().value.substring(2, getDefaultSku().value.length() - 1);\r
32648c62 634 }\r
878ddf1f 635}\r
636\r
637\r
638\r
639\r