5959import  javax .annotation .Nullable ;
6060import  java .util .*;
6161import  java .util .function .BiPredicate ;
62+ import  java .util .function .Consumer ;
6263import  java .util .function .Function ;
6364import  java .util .function .Predicate ;
6465
7475 * ItemStack: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/ItemStack.html 
7576 * 
7677 * @author Crypto Morin 
77-  * @version 7.1 .0 
78+  * @version 7.2 .0 
7879 * @see XMaterial 
7980 * @see XPotion 
8081 * @see SkullUtils 
@@ -366,7 +367,7 @@ public static Map<String, Object> serialize(@Nonnull ItemStack item) {
366367     */ 
367368    @ Nonnull 
368369    public  static  ItemStack  deserialize (@ Nonnull  ConfigurationSection  config ) {
369-         return  edit (new  ItemStack (Material .AIR ), config , Function .identity ());
370+         return  edit (new  ItemStack (Material .AIR ), config , Function .identity (),  null );
370371    }
371372
372373    private  static  List <String > splitNewLine (String  str ) {
@@ -397,19 +398,45 @@ private static List<String> splitNewLine(String str) {
397398        return  list ;
398399    }
399400
401+     @ Nonnull 
402+     public  static  ItemStack  deserialize (@ Nonnull  ConfigurationSection  config ,
403+                                         @ Nonnull  Function <String , String > translator ) {
404+         return  deserialize (config , translator , null );
405+     }
406+ 
400407    /** 
401408     * Deserialize an ItemStack from the config. 
402409     * 
403410     * @param config the config section to deserialize the ItemStack object from. 
404411     * 
405412     * @return an edited ItemStack. 
406-      * @since 7.0.0 
413+      * @since 7.2.0 
414+      */ 
415+     @ Nonnull 
416+     public  static  ItemStack  deserialize (@ Nonnull  ConfigurationSection  config ,
417+                                         @ Nonnull  Function <String , String > translator ,
418+                                         @ Nullable  Consumer <Exception > restart ) {
419+         return  edit (new  ItemStack (Material .AIR ), config , translator , restart );
420+     }
421+ 
422+ 
423+     /** 
424+      * Deserialize an ItemStack from a {@code Map}. 
425+      * 
426+      * @param serializedItem the map holding the item configurations to deserialize 
427+      *                       the ItemStack object from. 
428+      * @param translator     the translator to use for translating the item's name. 
429+      * 
430+      * @return a deserialized ItemStack. 
407431     */ 
408432    @ Nonnull 
409-     public  static  ItemStack  deserialize (@ Nonnull  ConfigurationSection  config , @ Nonnull  Function <String , String > translator ) {
410-         return  edit (new  ItemStack (Material .AIR ), config , translator );
433+     public  static  ItemStack  deserialize (@ Nonnull  Map <String , Object > serializedItem , @ Nonnull  Function <String , String > translator ) {
434+         Objects .requireNonNull (serializedItem , "serializedItem cannot be null." );
435+         Objects .requireNonNull (translator , "translator cannot be null." );
436+         return  deserialize (mapToConfigSection (serializedItem ), translator );
411437    }
412438
439+ 
413440    /** 
414441     * Deserialize an ItemStack from the config. 
415442     * 
@@ -420,16 +447,45 @@ public static ItemStack deserialize(@Nonnull ConfigurationSection config, @Nonnu
420447     */ 
421448    @ SuppressWarnings ("deprecation" )
422449    @ Nonnull 
423-     public  static  ItemStack  edit (@ Nonnull  ItemStack  item , @ Nonnull  ConfigurationSection  config , @ Nonnull  Function <String , String > translator ) {
450+     public  static  ItemStack  edit (@ Nonnull  ItemStack  item ,
451+                                  @ Nonnull  ConfigurationSection  config ,
452+                                  @ Nonnull  Function <String , String > translator ,
453+                                  @ Nullable  Consumer <Exception > restart ) {
424454        Objects .requireNonNull (item , "Cannot operate on null ItemStack, considering using an AIR ItemStack instead" );
425455        Objects .requireNonNull (config , "Cannot deserialize item to a null configuration section." );
426456        Objects .requireNonNull (translator , "Translator function cannot be null" );
427457
428458        // Material 
429459        String  materialName  = config .getString ("material" );
430-         Optional <XMaterial > material  = Strings .isNullOrEmpty (materialName ) ?
431-                 Optional .empty () : XMaterial .matchXMaterial (materialName );
432-         if  (material .isPresent ()) material .get ().setType (item );
460+         if  (!Strings .isNullOrEmpty (materialName )) {
461+             Optional <XMaterial > materialOpt  = XMaterial .matchXMaterial (materialName );
462+             XMaterial  material ;
463+             if  (materialOpt .isPresent ()) material  = materialOpt .get ();
464+             else  {
465+                 UnknownMaterialCondition  unknownMaterialCondition  = new  UnknownMaterialCondition (materialName );
466+                 restart .accept (unknownMaterialCondition );
467+ 
468+                 if  (unknownMaterialCondition .hasSolution ()) material  = unknownMaterialCondition .solution ;
469+                 else  throw  unknownMaterialCondition ;
470+             }
471+ 
472+             if  (!material .isSupported ()) {
473+                 UnAcceptableMaterialCondition  unsupportedMaterialCondition  = new  UnAcceptableMaterialCondition (material , UnAcceptableMaterialCondition .Reason .UNSUPPORTED );
474+                 restart .accept (unsupportedMaterialCondition );
475+ 
476+                 if  (unsupportedMaterialCondition .hasSolution ()) material  = unsupportedMaterialCondition .solution ;
477+                 else  throw  unsupportedMaterialCondition ;
478+             }
479+             if  (XTag .INVENTORY_NOT_DISPLAYABLE .isTagged (material )) {
480+                 UnAcceptableMaterialCondition  unsupportedMaterialCondition  = new  UnAcceptableMaterialCondition (material , UnAcceptableMaterialCondition .Reason .NOT_DISPLAYABLE );
481+                 restart .accept (unsupportedMaterialCondition );
482+ 
483+                 if  (unsupportedMaterialCondition .hasSolution ()) material  = unsupportedMaterialCondition .solution ;
484+                 else  throw  unsupportedMaterialCondition ;
485+             }
486+ 
487+             material .setType (item );
488+         }
433489
434490        // Amount 
435491        int  amount  = config .getInt ("amount" );
@@ -1151,4 +1207,54 @@ public static int firstPartialOrEmpty(@Nonnull Inventory inventory, @Nullable It
11511207        }
11521208        return  -1 ;
11531209    }
1210+ 
1211+     public  static  class  MaterialCondition  extends  RuntimeException  {
1212+         protected  XMaterial  solution ;
1213+ 
1214+         public  MaterialCondition (String  message ) {
1215+             super (message );
1216+         }
1217+ 
1218+         public  void  setSolution (XMaterial  solution ) {
1219+             this .solution  = solution ;
1220+         }
1221+ 
1222+         public  boolean  hasSolution () {
1223+             return  this .solution  != null ;
1224+         }
1225+     }
1226+ 
1227+     public  static  final  class  UnknownMaterialCondition  extends  MaterialCondition  {
1228+         private  final  String  material ;
1229+ 
1230+         public  UnknownMaterialCondition (String  material ) {
1231+             super ("Unknown material: "  + material );
1232+             this .material  = material ;
1233+         }
1234+ 
1235+         public  String  getMaterial () {
1236+             return  material ;
1237+         }
1238+     }
1239+ 
1240+     public  static  final  class  UnAcceptableMaterialCondition  extends  MaterialCondition  {
1241+         private  final  XMaterial  material ;
1242+         private  final  Reason  reason ;
1243+ 
1244+         public  UnAcceptableMaterialCondition (XMaterial  material , Reason  reason ) {
1245+             super ("Unacceptable material: "  + material .name () + " ("  + reason .name () + ')' );
1246+             this .material  = material ;
1247+             this .reason  = reason ;
1248+         }
1249+ 
1250+         public  Reason  getReason () {
1251+             return  reason ;
1252+         }
1253+ 
1254+         public  XMaterial  getMaterial () {
1255+             return  material ;
1256+         }
1257+ 
1258+         public  enum  Reason  {UNSUPPORTED , NOT_DISPLAYABLE }
1259+     }
11541260}
0 commit comments