public float getSavedFloat(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getFloat(name, 0f);
    }

/**
 * BobEngine - 2D game engine for Android
 */
package com.bobbyloujo.bobengine.extra;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

/**
 * This helper class contains some useful functionality for your app.
 *
 * Created by Benjamin on 2/13/2015.
 */
public class BobHelper {

    // Constants
    final // The flags for immersive mode
    int // The flags for immersive mode
    VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;

    // Data
    // Real width of the screen in pixels
    private int screenWidth;

    // Real height of the screen in pixels
    private int screenHeight;

    // Flag that determines if Immersive Mode is in use
    private boolean useImmersive = false;

    // Name of shared preferences file for saving data
    private String save = "save";

    // Objects
    private Activity activity;

    private WindowManager wm;

    private Point size;

    /**
     * You should initialize your BobHelper in or after onCreate() of activity.
     * @param activity - The activity that this BobHelper is tied to.
     */
    @SuppressLint("NewApi")
    public BobHelper(Activity activity) {
        this.activity = activity;
        wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        size = new Point();
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
            screenHeight = size.y;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenWidth = wm.getDefaultDisplay().getWidth();
            screenHeight = wm.getDefaultDisplay().getHeight();
        }
        ActivityManager am = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        Log.i("info", Integer.toString(am.getMemoryClass()) + "MB ram available.");
    }

    public void onResume() {
        if (useImmersive) {
            useImmersiveMode();
        }
    }

    /**
     * Uses KitKat's immersive mode. Immersive mode only works on Android 4.4.2
     * and up. There is no need to check for version number when using this
     * method. This method will handle older versions for you.
     */
    @SuppressLint("NewApi")
    public void useImmersiveMode() {
        try {
            // Immersive mode (Will not work on versions prior to 4.4.2)
            // Set the flags for immersive mode
            activity.getWindow().getDecorView().setSystemUiVisibility(VISIBILITY);
            // Add a listener to detect if we have lost immersive mode
            UIChangeListener();
            wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
            size = new Point();
            // Get -REAL- screen size. This excludes the navbar, which isn't visible
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
            screenHeight = size.y;
            useImmersive = true;
        } catch (NoSuchMethodError e) {
            // Immersive mode not supported (Android version < 4.4.2)
            // Get KitKat!
            Log.d("BobEngine", "Immersive mode not supported. (Android version < 4.4.2)");
        }
    }

    /**
     * This method creates a listener that will detect when immersive mode is
     * lost and get it back. Needs to be called again in onResume.
     */
    @SuppressLint("NewApi")
    private void UIChangeListener() {
        final View decorView = activity.getWindow().getDecorView();
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {

            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                    decorView.setSystemUiVisibility(VISIBILITY);
                }
            }
        });
    }

    /**
     * Returns the width of the screen.

     *

     * On devices using API level 13 and higher, this function will return the
     * real width of the screen including things like the navigation bar and
     * title bar.

     *

     * BobView includes a function to get just the width of the view.
     *
     * @return - Width of the screen, in pixels.
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public int getScreenWidth() {
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenWidth = wm.getDefaultDisplay().getWidth();
        }
        return screenWidth;
    }

    /**
     * Returns the width of the screen.

     *

     * On devices using API level 13 and higher, this function will return the
     * real height of the screen including things like the navigation bar and
     * title bar.

     *

     * BobView includes a function to get just the height of the view.
     *
     * @return - Width of the screen, in pixels.
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public int getScreenHeight() {
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenHeight = size.y;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenHeight = wm.getDefaultDisplay().getHeight();
        }
        return screenHeight;
    }

    /**
     * Set the save file to use with saveInt()... getSavedInt()... etc.
     * @param fileName
     */
    public void setSaveFile(String fileName) {
        save = fileName;
    }

    /**
     * Save an integer value. It can be retrieved even after the application has quit
     * by calling getSavedInt();
     *
     * @param name  - name of the saved integer. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveInt(String name, int value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putInt(name, value);
        edit.commit();
    }

    /**
     * Save an boolean value. It can be retrieved even after the application has quit
     * by calling getSavedBool();
     *
     * @param name  - name of the saved boolean. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveBool(String name, boolean value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putBoolean(name, value);
        edit.commit();
    }

    /**
     * Save an float value. It can be retrieved even after the application has quit
     * by calling getSavedFloat();
     *
     * @param name  - name of the saved float. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveFloat(String name, float value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putFloat(name, value);
        edit.commit();
    }

    /**
     * Save an string value. It can be retrieved even after the application has quit
     * by calling getSavedString();
     *
     * @param name  - name of the saved string. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveString(String name, String value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putString(name, value);
        edit.commit();
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0 if name doesn't exist.
     */
    public int getSavedInt(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getInt(name, 0);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0f if name doesn't exist.
     */

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. false if name doesn't exist.
     */
    public boolean getSavedBool(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getBoolean(name, false);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. "" if name doesn't exist.
     */
    public String getSavedString(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getString(name, "");
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0 if name doesn't exist.
     */
    public int getSavedInt(String name, final int DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getInt(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0f if name doesn't exist.
     */
    public float getSavedFloat(String name, final float DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getFloat(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. false if name doesn't exist.
     */
    public boolean getSavedBool(String name, final boolean DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getBoolean(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. "" if name doesn't exist.
     */
    public String getSavedString(String name, final String DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getString(name, DEFAULT);
    }
}


if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                    decorView.setSystemUiVisibility(VISIBILITY);
                }

/**
 * BobEngine - 2D game engine for Android
 */
package com.bobbyloujo.bobengine.extra;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

/**
 * This helper class contains some useful functionality for your app.
 *
 * Created by Benjamin on 2/13/2015.
 */
public class BobHelper {

    // Constants
    final // The flags for immersive mode
    int // The flags for immersive mode
    VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;

    // Data
    // Real width of the screen in pixels
    private int screenWidth;

    // Real height of the screen in pixels
    private int screenHeight;

    // Flag that determines if Immersive Mode is in use
    private boolean useImmersive = false;

    // Name of shared preferences file for saving data
    private String save = "save";

    // Objects
    private Activity activity;

    private WindowManager wm;

    private Point size;

    /**
     * You should initialize your BobHelper in or after onCreate() of activity.
     * @param activity - The activity that this BobHelper is tied to.
     */
    @SuppressLint("NewApi")
    public BobHelper(Activity activity) {
        this.activity = activity;
        wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        size = new Point();
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
            screenHeight = size.y;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenWidth = wm.getDefaultDisplay().getWidth();
            screenHeight = wm.getDefaultDisplay().getHeight();
        }
        ActivityManager am = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        Log.i("info", Integer.toString(am.getMemoryClass()) + "MB ram available.");
    }

    public void onResume() {
        if (useImmersive) {
            useImmersiveMode();
        }
    }

    /**
     * Uses KitKat's immersive mode. Immersive mode only works on Android 4.4.2
     * and up. There is no need to check for version number when using this
     * method. This method will handle older versions for you.
     */
    @SuppressLint("NewApi")
    public void useImmersiveMode() {
        try {
            // Immersive mode (Will not work on versions prior to 4.4.2)
            // Set the flags for immersive mode
            activity.getWindow().getDecorView().setSystemUiVisibility(VISIBILITY);
            // Add a listener to detect if we have lost immersive mode
            UIChangeListener();
            wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
            size = new Point();
            // Get -REAL- screen size. This excludes the navbar, which isn't visible
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
            screenHeight = size.y;
            useImmersive = true;
        } catch (NoSuchMethodError e) {
            // Immersive mode not supported (Android version < 4.4.2)
            // Get KitKat!
            Log.d("BobEngine", "Immersive mode not supported. (Android version < 4.4.2)");
        }
    }

    /**
     * This method creates a listener that will detect when immersive mode is
     * lost and get it back. Needs to be called again in onResume.
     */
    @SuppressLint("NewApi")
    private void UIChangeListener() {
        final View decorView = activity.getWindow().getDecorView();
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {

            @Override
            public void onSystemUiVisibilityChange(int visibility) {

}
        });
    }

    /**
     * Returns the width of the screen.

     *

     * On devices using API level 13 and higher, this function will return the
     * real width of the screen including things like the navigation bar and
     * title bar.

     *

     * BobView includes a function to get just the width of the view.
     *
     * @return - Width of the screen, in pixels.
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public int getScreenWidth() {
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenWidth = wm.getDefaultDisplay().getWidth();
        }
        return screenWidth;
    }

    /**
     * Returns the width of the screen.

     *

     * On devices using API level 13 and higher, this function will return the
     * real height of the screen including things like the navigation bar and
     * title bar.

     *

     * BobView includes a function to get just the height of the view.
     *
     * @return - Width of the screen, in pixels.
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public int getScreenHeight() {
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenHeight = size.y;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenHeight = wm.getDefaultDisplay().getHeight();
        }
        return screenHeight;
    }

    /**
     * Set the save file to use with saveInt()... getSavedInt()... etc.
     * @param fileName
     */
    public void setSaveFile(String fileName) {
        save = fileName;
    }

    /**
     * Save an integer value. It can be retrieved even after the application has quit
     * by calling getSavedInt();
     *
     * @param name  - name of the saved integer. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveInt(String name, int value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putInt(name, value);
        edit.commit();
    }

    /**
     * Save an boolean value. It can be retrieved even after the application has quit
     * by calling getSavedBool();
     *
     * @param name  - name of the saved boolean. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveBool(String name, boolean value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putBoolean(name, value);
        edit.commit();
    }

    /**
     * Save an float value. It can be retrieved even after the application has quit
     * by calling getSavedFloat();
     *
     * @param name  - name of the saved float. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveFloat(String name, float value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putFloat(name, value);
        edit.commit();
    }

    /**
     * Save an string value. It can be retrieved even after the application has quit
     * by calling getSavedString();
     *
     * @param name  - name of the saved string. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveString(String name, String value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putString(name, value);
        edit.commit();
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0 if name doesn't exist.
     */
    public int getSavedInt(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getInt(name, 0);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0f if name doesn't exist.
     */
    public float getSavedFloat(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getFloat(name, 0f);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. false if name doesn't exist.
     */
    public boolean getSavedBool(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getBoolean(name, false);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. "" if name doesn't exist.
     */
    public String getSavedString(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getString(name, "");
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0 if name doesn't exist.
     */
    public int getSavedInt(String name, final int DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getInt(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0f if name doesn't exist.
     */
    public float getSavedFloat(String name, final float DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getFloat(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. false if name doesn't exist.
     */
    public boolean getSavedBool(String name, final boolean DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getBoolean(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. "" if name doesn't exist.
     */
    public String getSavedString(String name, final String DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getString(name, DEFAULT);
    }
}


try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenHeight = size.y;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenHeight = wm.getDefaultDisplay().getHeight();
        }

/**
 * BobEngine - 2D game engine for Android
 */
package com.bobbyloujo.bobengine.extra;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

/**
 * This helper class contains some useful functionality for your app.
 *
 * Created by Benjamin on 2/13/2015.
 */
public class BobHelper {

    // Constants
    final // The flags for immersive mode
    int // The flags for immersive mode
    VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;

    // Data
    // Real width of the screen in pixels
    private int screenWidth;

    // Real height of the screen in pixels
    private int screenHeight;

    // Flag that determines if Immersive Mode is in use
    private boolean useImmersive = false;

    // Name of shared preferences file for saving data
    private String save = "save";

    // Objects
    private Activity activity;

    private WindowManager wm;

    private Point size;

    /**
     * You should initialize your BobHelper in or after onCreate() of activity.
     * @param activity - The activity that this BobHelper is tied to.
     */
    @SuppressLint("NewApi")
    public BobHelper(Activity activity) {
        this.activity = activity;
        wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        size = new Point();
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
            screenHeight = size.y;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenWidth = wm.getDefaultDisplay().getWidth();
            screenHeight = wm.getDefaultDisplay().getHeight();
        }
        ActivityManager am = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        Log.i("info", Integer.toString(am.getMemoryClass()) + "MB ram available.");
    }

    public void onResume() {
        if (useImmersive) {
            useImmersiveMode();
        }
    }

    /**
     * Uses KitKat's immersive mode. Immersive mode only works on Android 4.4.2
     * and up. There is no need to check for version number when using this
     * method. This method will handle older versions for you.
     */
    @SuppressLint("NewApi")
    public void useImmersiveMode() {
        try {
            // Immersive mode (Will not work on versions prior to 4.4.2)
            // Set the flags for immersive mode
            activity.getWindow().getDecorView().setSystemUiVisibility(VISIBILITY);
            // Add a listener to detect if we have lost immersive mode
            UIChangeListener();
            wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
            size = new Point();
            // Get -REAL- screen size. This excludes the navbar, which isn't visible
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
            screenHeight = size.y;
            useImmersive = true;
        } catch (NoSuchMethodError e) {
            // Immersive mode not supported (Android version < 4.4.2)
            // Get KitKat!
            Log.d("BobEngine", "Immersive mode not supported. (Android version < 4.4.2)");
        }
    }

    /**
     * This method creates a listener that will detect when immersive mode is
     * lost and get it back. Needs to be called again in onResume.
     */
    @SuppressLint("NewApi")
    private void UIChangeListener() {
        final View decorView = activity.getWindow().getDecorView();
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {

            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                    decorView.setSystemUiVisibility(VISIBILITY);
                }
            }
        });
    }

    /**
     * Returns the width of the screen.

     *

     * On devices using API level 13 and higher, this function will return the
     * real width of the screen including things like the navigation bar and
     * title bar.

     *

     * BobView includes a function to get just the width of the view.
     *
     * @return - Width of the screen, in pixels.
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public int getScreenWidth() {
        try {
            // Get screen dimensions
            // New method, might not work on old devices
            wm.getDefaultDisplay().getRealSize(size);
            screenWidth = size.x;
        } catch (NoSuchMethodError er) {
            // If new method didn't work, use depreciated methods
            screenWidth = wm.getDefaultDisplay().getWidth();
        }
        return screenWidth;
    }

    /**
     * Returns the width of the screen.

     *

     * On devices using API level 13 and higher, this function will return the
     * real height of the screen including things like the navigation bar and
     * title bar.

     *

     * BobView includes a function to get just the height of the view.
     *
     * @return - Width of the screen, in pixels.
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public int getScreenHeight() {

        return screenHeight;
    }

    /**
     * Set the save file to use with saveInt()... getSavedInt()... etc.
     * @param fileName
     */
    public void setSaveFile(String fileName) {
        save = fileName;
    }

    /**
     * Save an integer value. It can be retrieved even after the application has quit
     * by calling getSavedInt();
     *
     * @param name  - name of the saved integer. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveInt(String name, int value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putInt(name, value);
        edit.commit();
    }

    /**
     * Save an boolean value. It can be retrieved even after the application has quit
     * by calling getSavedBool();
     *
     * @param name  - name of the saved boolean. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveBool(String name, boolean value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putBoolean(name, value);
        edit.commit();
    }

    /**
     * Save an float value. It can be retrieved even after the application has quit
     * by calling getSavedFloat();
     *
     * @param name  - name of the saved float. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveFloat(String name, float value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putFloat(name, value);
        edit.commit();
    }

    /**
     * Save an string value. It can be retrieved even after the application has quit
     * by calling getSavedString();
     *
     * @param name  - name of the saved string. Will be used for retrieval.
     * @param value - value to save.
     */
    public void saveString(String name, String value) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putString(name, value);
        edit.commit();
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0 if name doesn't exist.
     */
    public int getSavedInt(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getInt(name, 0);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0f if name doesn't exist.
     */
    public float getSavedFloat(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getFloat(name, 0f);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. false if name doesn't exist.
     */
    public boolean getSavedBool(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getBoolean(name, false);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. "" if name doesn't exist.
     */
    public String getSavedString(String name) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getString(name, "");
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0 if name doesn't exist.
     */
    public int getSavedInt(String name, final int DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getInt(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. 0f if name doesn't exist.
     */
    public float getSavedFloat(String name, final float DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getFloat(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. false if name doesn't exist.
     */
    public boolean getSavedBool(String name, final boolean DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getBoolean(name, DEFAULT);
    }

    /**
     * Get a saved value.
     *
     * @param name - name of the saved value.
     * @return saved value of name. "" if name doesn't exist.
     */
    public String getSavedString(String name, final String DEFAULT) {
        SharedPreferences prefs = activity.getSharedPreferences(save, activity.MODE_PRIVATE);
        return prefs.getString(name, DEFAULT);
    }
}


package com.zrp.latte.ec.main.index.spec;

import com.chad.library.adapter.base.entity.SectionEntity;

public class SpecZoneBean extends SectionEntity<SpecZoneItemEntity> {

    private boolean mIsMore = false;

    private int mId = -1;

    public SpecZoneBean(SpecZoneItemEntity specItemEntity) {
        super(specItemEntity);
    }

    public SpecZoneBean(boolean isHeader, String header) {
        super(isHeader, header);
    }

    public boolean isMore() {
        return mIsMore;
    }

    public void setIsMore(boolean isMore) {
        this.mIsMore = isMore;
    }

    public int getId() {
        return mId;
    }


package com.zrp.latte.ec.main.index.spec;

import com.chad.library.adapter.base.entity.SectionEntity;

public class SpecZoneBean extends SectionEntity<SpecZoneItemEntity> {

    private boolean mIsMore = false;

    private int mId = -1;

    public SpecZoneBean(SpecZoneItemEntity specItemEntity) {
        super(specItemEntity);
    }

    public SpecZoneBean(boolean isHeader, String header) {
        super(isHeader, header);
    }

    public boolean isMore() {
        return mIsMore;
    }

    public void setIsMore(boolean isMore)

    public int getId() {
        return mId;
    }

    public void setId(int id) {
        this.mId = id;
    }
}


package com.zrp.latte.ec.main.index.spec;

import com.chad.library.adapter.base.entity.SectionEntity;

public class SpecZoneBean extends SectionEntity<SpecZoneItemEntity> {

    private boolean mIsMore = false;

    private int mId = -1;

    public SpecZoneBean(SpecZoneItemEntity specItemEntity) {
        super(specItemEntity);
    }

    public SpecZoneBean(boolean isHeader, String header) {
        super(isHeader, header);
    }

    public boolean isMore() {
        return mIsMore;
    }

    public void setIsMore(boolean isMore) {
        this.mIsMore = isMore;
    }

    public int getId() {
        return mI

    }

    public void setId(int id) {
        this.mId = id;
    }
}


NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception

package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

{
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo
        if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }
        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinadoXml);
        final NfeDadosMsg dados = new NfeDadosMsg();
        dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());
        if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);
        while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }
        return ome;
    }
}


{
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

    NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo
        if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }
        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinadoXml);
        final NfeDadosMsg dados = new NfeDadosMsg();
        dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());
        if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);
        while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }
        return ome;
    }
}


        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinadoXml);
        final NfeDadosMsg dados = new NfeDadosMsg();

package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

    NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception {
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo
        if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }
        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {

        dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());
        if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);
        while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }
        return ome;
    }
}


dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());

package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

    NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception {
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo
        if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }
        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinadoXml);
        final NfeDadosMsg dados = new NfeDadosMsg();

        if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);
        while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }
        return ome;
    }
}


if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

    NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception {
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo
        if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }
        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinadoXml);
        final NfeDadosMsg dados = new NfeDadosMsg();
        dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);
        while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }
        return ome;
    }
}


package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

    NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception {
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo
        if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }
        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinad

        final NfeDadosMsg dados = new NfeDadosMsg();
        dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());
        if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);
        while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }
        return ome;
    }
}


if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }

package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

    NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception {
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo

        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinadoXml);
        final NfeDadosMsg dados = new NfeDadosMsg();
        dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());
        if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);
        while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }
        return ome;
    }
}


while (children.hasNext()) {
            final OMElement omElement = (OMElement) children.next();
            if ((omElement != null) && (WSLoteEnvio.NFE_ELEMENTO.equals(omElement.getLocalName()))) {
                omElement.addAttribute("xmlns", NFeConfig.NAMESPACE, null);
            }
        }

package com.fincatto.documentofiscal.nfe310.webservices;

import com.fincatto.documentofiscal.DFLog;
import com.fincatto.documentofiscal.DFModelo;
import com.fincatto.documentofiscal.nfe.NFeConfig;
import com.fincatto.documentofiscal.nfe310.classes.NFAutorizador31;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvio;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetorno;
import com.fincatto.documentofiscal.nfe310.classes.lote.envio.NFLoteEnvioRetornoDados;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNota;
import com.fincatto.documentofiscal.nfe310.classes.nota.NFNotaInfoSuplementar;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraChave;
import com.fincatto.documentofiscal.nfe310.utils.NFGeraQRCode;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeAutorizacaoLoteResult;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsg;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeCabecMsgE;
import com.fincatto.documentofiscal.nfe310.webservices.gerado.NfeAutorizacaoStub.NfeDadosMsg;
import com.fincatto.documentofiscal.utils.DFAssinaturaDigital;
import com.fincatto.documentofiscal.validadores.DFXMLValidador;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Iterator;

class WSLoteEnvio implements DFLog {

    private static final String NFE_ELEMENTO = "NFe";

    private final NFeConfig config;

    WSLoteEnvio(final NFeConfig config) {
        this.config = config;
    }

    NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        return this.comunicaLote(loteAssinadoXml, modelo);
    }

    NFLoteEnvioRetornoDados enviaLote(final NFLoteEnvio lote) throws Exception {
        final NFLoteEnvio loteAssinado = this.getLoteAssinado(lote);
        // comunica o lote
        final NFLoteEnvioRetorno loteEnvioRetorno = this.comunicaLote(loteAssinado.toString(), loteAssinado.getNotas().get(0).getInfo().getIdentificacao().getModelo());
        return new NFLoteEnvioRetornoDados(loteEnvioRetorno, loteAssinado);
    }

    /**
     * Retorna o Lote assinado.
     */
    NFLoteEnvio getLoteAssinado(final NFLoteEnvio lote) throws Exception {
        // adiciona a chave e o dv antes de assinar
        for (final NFNota nota : lote.getNotas()) {
            final NFGeraChave geraChave = new NFGeraChave(nota);
            nota.getInfo().getIdentificacao().setCodigoRandomico(StringUtils.defaultIfBlank(nota.getInfo().getIdentificacao().getCodigoRandomico(), geraChave.geraCodigoRandomico()));
            nota.getInfo().getIdentificacao().setDigitoVerificador(geraChave.getDV());
            nota.getInfo().setIdentificador(geraChave.getChaveAcesso());
        }
        // assina o lote
        final String documentoAssinado = new DFAssinaturaDigital(this.config).assinarDocumento(lote.toString());
        final NFLoteEnvio loteAssinado = this.config.getPersister().read(NFLoteEnvio.class, documentoAssinado);
        // verifica se nao tem NFCe junto com NFe no lote e gera qrcode (apos assinar mesmo, eh assim)
        int qtdNF = 0, qtdNFC = 0;
        for (final NFNota nota : loteAssinado.getNotas()) {
            switch(nota.getInfo().getIdentificacao().getModelo()) {
                case NFE:
                    qtdNF++;
                    break;
                case NFCE:
                    final NFGeraQRCode geraQRCode = new NFGeraQRCode(nota, this.config);
                    nota.setInfoSuplementar(new NFNotaInfoSuplementar());
                    nota.getInfoSuplementar().setQrCode(geraQRCode.getQRCode());
                    qtdNFC++;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Modelo de nota desconhecida: %s", nota.getInfo().getIdentificacao().getModelo()));
            }
        }
        // verifica se todas as notas do lote sao do mesmo modelo
        if ((qtdNF > 0) && (qtdNFC > 0)) {
            throw new IllegalArgumentException("Lote contendo notas de modelos diferentes!");
        }
        return loteAssinado;
    }

    private NFLoteEnvioRetorno comunicaLote(final String loteAssinadoXml, final DFModelo modelo) throws Exception {
        // valida o lote assinado, para verificar se o xsd foi satisfeito, antes de comunicar com a sefaz
        DFXMLValidador.validaLote(loteAssinadoXml);
        // envia o lote para a sefaz
        final OMElement omElement = this.nfeToOMElement(loteAssinadoXml);
        final NfeDadosMsg dados = new NfeDadosMsg();
        dados.setExtraElement(omElement);
        final NfeCabecMsgE cabecalhoSOAP = this.getCabecalhoSOAP();
        this.getLogger().debug(omElement.toString());
        // define o tipo de emissao
        final NFAutorizador31 autorizador = NFAutorizador31.valueOfTipoEmissao(this.config.getTipoEmissao(), this.config.getCUF());
        final String endpoint = DFModelo.NFE.equals(modelo) ? autorizador.getNfeAutorizacao(this.config.getAmbiente()) : autorizador.getNfceAutorizacao(this.config.getAmbiente());
        if (endpoint == null) {
            throw new IllegalArgumentException("Nao foi possivel encontrar URL para Autorizacao " + modelo.name() + ", autorizador " + autorizador.name());
        }
        final NfeAutorizacaoLoteResult autorizacaoLoteResult = new NfeAutorizacaoStub(endpoint, config).nfeAutorizacaoLote(dados, cabecalhoSOAP);
        final NFLoteEnvioRetorno loteEnvioRetorno = this.config.getPersister().read(NFLoteEnvioRetorno.class, autorizacaoLoteResult.getExtraElement().toString());
        this.getLogger().debug(loteEnvioRetorno.toString());
        return loteEnvioRetorno;
    }

    private NfeCabecMsgE getCabecalhoSOAP() {
        final NfeCabecMsg cabecalho = new NfeCabecMsg();
        cabecalho.setCUF(this.config.getCUF().getCodigoIbge());
        cabecalho.setVersaoDados(this.config.getVersao());
        final NfeCabecMsgE cabecalhoSOAP = new NfeCabecMsgE();
        cabecalhoSOAP.setNfeCabecMsg(cabecalho);
        return cabecalhoSOAP;
    }

    private OMElement nfeToOMElement(final String documento) throws XMLStreamException {
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty(XMLInputFactory.IS_COALESCING, false);
        final XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(documento));
        final StAXOMBuilder builder = new StAXOMBuilder(reader);
        final OMElement ome = builder.getDocumentElement();
        final Iterator<?> children = ome.getChildrenWithLocalName(WSLoteEnvio.NFE_ELEMENTO);


package io.gomint.inventory.item;

import io.gomint.GoMint;

/**
 * @author geNAZt
 * @version 1.0
 * @stability 3
 */
public interface ItemBeetroot extends ItemFood<ItemBeetroot> {

    /**
     * Create a new item stack with given class and amount
     *
     * @param amount which is used for the creation
     * @return freshly generated item
     */

{
        return GoMint.instance().createItemStack(ItemBeetroot.class, amount);
    }
}


{
        return GoMint.instance().createItemStack(ItemBeetroot.class, amount);
    }

package io.gomint.inventory.item;

import io.gomint.GoMint;

/**
 * @author geNAZt
 * @version 1.0
 * @stability 3
 */
public interface ItemBeetroot extends ItemFood<ItemBeetroot> {

    /**
     * Create a new item stack with given class and amount
     *
     * @param amount which is used for the creation
     * @return freshly generated item
     */
    static ItemBeetroot create(int amount)


package io.gomint.inventory.item;

import io.gomint.GoMint;

/**
 * @author geNAZt
 * @version 1.0
 * @stability 3
 */
public interface ItemBeetroot extends ItemFood<ItemBeetroot> {

    /**
     * Create a new item stack with given class and amount
     *
     * @param amount which is used for the creation
     * @return freshly generated item
     */
    static ItemBeetroot create(int amount) {
        return G


static ItemBeetroot create(int amount) {
        return GoMint.instance().createItemStack(ItemBeetroot.class, amount);
    }