org.cvasilak.jboss.mobile.app.fragments.RuntimeViewFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.cvasilak.jboss.mobile.app.fragments.RuntimeViewFragment.java

Source

/*
 * JBoss Admin
 * Copyright 2013, Christos Vasilakis, and individual contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.cvasilak.jboss.mobile.app.fragments;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.*;
import android.widget.*;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.cvasilak.jboss.mobile.app.JBossAdminApplication;
import org.cvasilak.jboss.mobile.app.R;
import org.cvasilak.jboss.mobile.app.activities.JBossServerRootActivity;
import org.cvasilak.jboss.mobile.app.fragments.dialogs.ErrorDialogFragment;
import org.cvasilak.jboss.mobile.app.fragments.dialogs.ParameterizedDialogFragment;
import org.cvasilak.jboss.mobile.app.fragments.dialogs.ProgressDialogFragment;
import org.cvasilak.jboss.mobile.app.net.Callback;
import org.cvasilak.jboss.mobile.app.net.JBossOperationsManager;
import org.cvasilak.jboss.mobile.app.net.JBossOperationsManager.HostStatus;
import org.cvasilak.jboss.mobile.app.util.commonsware.MergeAdapter;

import java.util.*;

import static org.cvasilak.jboss.mobile.app.net.JBossOperationsManager.HostStatus.*;

public class RuntimeViewFragment extends ListFragment {

    private static final String TAG = RuntimeViewFragment.class.getSimpleName();

    private JBossAdminApplication application;

    // the Choose Server button on top of the list
    private Button chooseServer;

    // the adapter that holds the hosts listview
    private HostAdapter hostAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d(TAG, "@onCreate()");

        setRetainInstance(true);

        application = (JBossAdminApplication) getActivity().getApplication();

        // inform runtime that we have action buttons
        setHasOptionsMenu(true);

        // determine whether we are running in STANDALONE or DOMAIN mode
        // and update table view accordingly
        if (application.getOperationsManager().getDomainHost() == null) {
            ProgressDialogFragment.showDialog(getActivity(), R.string.fetchingDomainInfo);

            application.getOperationsManager().fetchActiveServerInformation(new Callback() {
                @Override
                public void onSuccess(JsonElement reply) {
                    ProgressDialogFragment.dismissDialog(getActivity());

                    JsonObject hosts = reply.getAsJsonObject();

                    String host = null;
                    String server = null;

                    for (Map.Entry<String, JsonElement> e : hosts.entrySet()) {
                        host = e.getKey();

                        JsonObject hostInfo = e.getValue().getAsJsonObject();
                        JsonObject servers = hostInfo.getAsJsonObject("server");

                        for (Map.Entry<String, JsonElement> p : servers.entrySet()) {
                            server = p.getKey();
                            break;
                        }

                        if (server != null)
                            break;
                    }

                    application.getOperationsManager().changeActiveMonitoringServer(host, server);

                    // update table to reflect mode
                    buildTable();
                }

                @Override
                public void onFailure(Exception e) {
                    ProgressDialogFragment.dismissDialog(getActivity());

                    // HTTP/1.1 500 Internal Server Error
                    // occurred doing :read-children-resources(child-type=host)
                    // the server is running in standalone mode, we can live with that
                    buildTable();
                }
            });
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        ActionBar bar = ((ActionBarActivity) getActivity()).getSupportActionBar();
        bar.setTitle(application.getOperationsManager().getServer().getName());
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_logout, menu);

        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.logout) {
            ((JBossServerRootActivity) getActivity()).onBackPressed();
            return (true);
        }

        return (super.onOptionsItemSelected(item));
    }

    private void buildTable() {
        Map<String, List<String>> table = new HashMap<String, List<String>>();

        table.put("Server Status", Arrays.asList("Configuration", "JVM"));

        List<String> metrics = new ArrayList<String>(
                Arrays.asList("Data Sources", "JMS Destinations", "Transactions"));
        // 'Web' section metrics is compatible (for now) only with MANAGEMENT_VERSION_1
        // TODO ('Undertow' subsystem metrics can possible replace)
        if (application.getOperationsManager()
                .getVersion() == JBossOperationsManager.ManagementVersion.MANAGEMENT_VERSION_1) {
            metrics.add("Web");
        }

        table.put("Subsystem Metrics", metrics);

        if (application.getOperationsManager().isDomainController()) {
            table.put("Deployments", Arrays.asList("Deployment Content", "Server Groups"));
        } else {
            table.put("Deployments", Arrays.asList("Manage Deployments"));
        }

        MergeAdapter adapter = new MergeAdapter();

        // cater for domain mode and display a button
        // for the user to change the active server
        if (application.getOperationsManager().isDomainController()) {
            chooseServer = new Button(getActivity());
            chooseServer.setText(application.getOperationsManager().getDomainHost() + ":"
                    + application.getOperationsManager().getDomainServer());
            chooseServer.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_servers_selection, 0);
            chooseServer.setTypeface(null, Typeface.ITALIC);
            chooseServer.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showDomainHostChooser();
                }
            });

            adapter.addView(chooseServer);
        }

        for (Map.Entry<String, List<String>> entry : table.entrySet()) {
            // add section header
            TextView section = new TextView(getActivity());
            section.setBackgroundColor(Color.DKGRAY);
            section.setPadding(15, 10, 0, 10);
            section.setText(entry.getKey());
            adapter.addView(section);

            // add section data
            adapter.addAdapter(
                    new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, entry.getValue()));
        }

        setListAdapter(adapter);
    }

    @Override
    public void onListItemClick(ListView list, View view, int position, long id) {
        String value = (String) list.getItemAtPosition(position);

        Fragment fragment = null;

        if (value.equals("Configuration")) {
            fragment = new ConfigurationViewFragment();
        } else if (value.equals("JVM")) {
            fragment = new JVMMetricsViewFragment();
        } else if (value.equals("Data Sources")) {
            fragment = new DataSourcesViewFragment();
        } else if (value.equals("JMS Destinations")) {
            fragment = new JMSTypeSelectorViewFragment();
        } else if (value.equals("Transactions")) {
            fragment = new TransactionMetricsViewFragment();
        } else if (value.equals("Web")) {
            fragment = new WebConnectorTypeSelectorViewFragment();
        } else if (value.equals("Deployment Content")) {
            fragment = DeploymentsViewFragment.newInstance(null, DeploymentsViewFragment.Mode.DOMAIN_MODE);
        } else if (value.equals("Server Groups")) {
            fragment = new DomainServerGroupsViewFragment();
        } else if (value.equals("Manage Deployments")) {
            fragment = DeploymentsViewFragment.newInstance(null, DeploymentsViewFragment.Mode.STANDALONE_MODE);
        }

        ((JBossServerRootActivity) getActivity()).addFragment(fragment);
    }

    public void showDomainHostChooser() {
        ProgressDialogFragment.showDialog(getActivity(), R.string.queryingServer);

        application.getOperationsManager().fetchDomainHostInfoInformation(new Callback() {
            @Override
            public void onSuccess(JsonElement reply) {
                JsonArray jsonArr = reply.getAsJsonArray();

                // if only one host exists in the domain,
                // no need to display the host chooser dialog
                // immediately show the servers dialog for this host
                if (jsonArr.size() == 1) {
                    showDomainServersDialog(jsonArr.get(0).getAsString(), false);
                    return;
                }

                ProgressDialogFragment.dismissDialog(getActivity());

                final ArrayAdapter<String> hosts = new ArrayAdapter<String>(getActivity(),
                        android.R.layout.simple_list_item_single_choice);

                // will hold the default selection host position
                // when the list is displayed
                int selPos = -1;

                String activeHost = application.getOperationsManager().getDomainHost();

                for (int i = 0; i < jsonArr.size(); i++) {
                    String host = jsonArr.get(i).getAsString();

                    if (host.equals(activeHost))
                        selPos = i;

                    hosts.add(host);
                }

                AlertDialog.Builder hostsDialog = new AlertDialog.Builder(getActivity());

                hostsDialog.setTitle(R.string.select_host);
                hostsDialog.setSingleChoiceItems(hosts, selPos, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        showDomainServersDialog(hosts.getItem(which), true);
                    }
                });

                hostsDialog.setPositiveButton(R.string.next, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        int selectedPosition = ((AlertDialog) dialogInterface).getListView()
                                .getCheckedItemPosition();

                        showDomainServersDialog(hosts.getItem(selectedPosition), true);
                    }
                });

                hostsDialog.setCancelable(false);

                ParameterizedDialogFragment dialog = new ParameterizedDialogFragment(hostsDialog);
                dialog.show(getActivity().getSupportFragmentManager(), null);
            }

            @Override
            public void onFailure(Exception e) {
                ProgressDialogFragment.dismissDialog(getActivity());

                ErrorDialogFragment.showDialog(getActivity(), e.getMessage());
            }
        });
    }

    public void showDomainServersDialog(final String host, boolean showProgress) {
        if (showProgress)
            ProgressDialogFragment.showDialog(getActivity(), R.string.queryingServer);

        application.getOperationsManager().fetchServersInformation(host, new Callback() {
            @Override
            public void onSuccess(JsonElement reply) {
                ProgressDialogFragment.dismissDialog(getActivity());

                hostAdapter = new HostAdapter();

                JsonObject jsonObj = reply.getAsJsonObject();

                for (Map.Entry<String, JsonElement> e : jsonObj.entrySet()) {
                    String name = e.getKey();

                    JsonObject info = e.getValue().getAsJsonObject();

                    HostStatus status = HostStatus.valueOf(info.get("status").getAsString());
                    String group = info.get("group").getAsString();

                    hostAdapter.add(new Server(name, host, group, status));
                }

                AlertDialog.Builder serversDialog = new AlertDialog.Builder(getActivity());

                serversDialog.setTitle(R.string.select_server);
                serversDialog.setSingleChoiceItems(hostAdapter, -1, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Server server = hostAdapter.getItem(which);

                        if (server.status == STARTED) {
                            // update operations manager
                            application.getOperationsManager().changeActiveMonitoringServer(host, server.name);

                            // update button view
                            chooseServer.setText(application.getOperationsManager().getDomainHost() + ":"
                                    + application.getOperationsManager().getDomainServer());

                            dialog.dismiss();
                        }
                    }
                });

                serversDialog.setCancelable(false);

                ParameterizedDialogFragment dialog = new ParameterizedDialogFragment(serversDialog);
                dialog.show(getActivity().getSupportFragmentManager(), null);
            }

            @Override
            public void onFailure(Exception e) {
                ProgressDialogFragment.dismissDialog(getActivity());

                ErrorDialogFragment.showDialog(getActivity(), e.getMessage());
            }
        });
    }

    public void toggleServerStatus(final Server server) {
        final String actionStr = (server.status == STARTED ? "Stop" : "Start");

        final boolean start = actionStr.equals("Start");

        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());

        alertDialog.setTitle(String.format(getString(R.string.dialog_confirm_action_title), actionStr))
                .setMessage(String.format(getString(R.string.dialog_confirm_action_body), actionStr, server.name))

                .setNegativeButton(getString(R.string.dialog_button_NO), null)
                .setPositiveButton(getString(R.string.dialog_button_YES), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        ProgressDialogFragment.showDialog(getActivity(), R.string.applyingAction);

                        application.getOperationsManager().changeStatus(server.belongingHost, server.name, start,
                                new Callback() {
                                    @Override
                                    public void onSuccess(JsonElement reply) {
                                        ProgressDialogFragment.dismissDialog(getActivity());

                                        String status = reply.getAsString();

                                        boolean error = false;

                                        if (start && !status.equals("STARTED"))
                                            error = true;

                                        if (!start && !status.equals("STOPPED"))
                                            error = true;

                                        Toast.makeText(getActivity(),
                                                (error ? getString(R.string.failed) : getString(R.string.success)),
                                                Toast.LENGTH_SHORT).show();

                                        // update model
                                        if (!error) {
                                            server.status = start ? STARTED : STOPPED;
                                        }

                                        // refresh view
                                        hostAdapter.notifyDataSetChanged();
                                    }

                                    @Override
                                    public void onFailure(Exception e) {
                                        ProgressDialogFragment.dismissDialog(getActivity());

                                        ErrorDialogFragment.showDialog(getActivity(), e.getMessage());
                                    }
                                });
                    }
                });

        ParameterizedDialogFragment dialog = new ParameterizedDialogFragment(alertDialog);
        dialog.show(getActivity().getSupportFragmentManager(), null);
    }

    class HostAdapter extends ArrayAdapter<Server> {
        HostAdapter() {
            super(getActivity(), R.layout.server_row, R.id.server_name);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = super.getView(position, convertView, parent);
            ViewHolder holder = (ViewHolder) row.getTag();

            if (holder == null) {
                holder = new ViewHolder(row);
                row.setTag(holder);
            }

            holder.populateFrom(getItem(position));

            // only enable toggleStatus for status's other than pending
            if (getItem(position).status != STARTING && getItem(position).status != STOPPING) {
                holder.startStop.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        toggleServerStatus((Server) v.getTag());
                    }
                });
            }
            return (row);
        }

        @Override
        public boolean areAllItemsEnabled() {
            return false;
        }

        @Override
        public boolean isEnabled(int position) {
            // disable item click if the server is not yet started
            return getItem(position).status == STARTED;
        }
    }

    class ViewHolder {
        ImageView status = null;
        TextView name = null;
        TextView group = null;
        ImageView startStop = null;

        ViewHolder(View row) {
            this.status = (ImageView) row.findViewById(R.id.server_status_icon);
            this.name = (TextView) row.findViewById(R.id.server_name);
            this.group = (TextView) row.findViewById(R.id.server_group_name);
            this.startStop = (ImageView) row.findViewById(R.id.server_start_stop);
        }

        void populateFrom(Server server) {
            name.setText(server.name);

            // handle text color becoming invisible in 'Gingerbread'
            // see https://code.google.com/p/android/issues/detail?id=922
            if (Build.VERSION.SDK_INT == 10) {
                name.setTextColor(Color.BLACK);
            }

            group.setText(server.group);

            switch (server.status) {
            case STARTED:
                status.setImageResource(R.drawable.ic_element_up);
                startStop.setImageResource(R.drawable.ic_stop);
                startStop.setTag(server);
                break;
            case DISABLED:
            case STOPPED:
            case FAILED:
                status.setImageResource(R.drawable.ic_element_down);
                startStop.setImageResource(R.drawable.ic_start);
                startStop.setTag(server);
                break;
            case STARTING:
            case STOPPING:
                status.setImageResource(R.drawable.ic_element_down);
                startStop.setImageResource(R.drawable.ic_clear);
                startStop.setTag(null);
                break;
            }
        }
    }

    class Server {
        String name;
        String group;
        String belongingHost;
        HostStatus status;

        Server(String name, String belongingHost, String group, HostStatus status) {
            this.name = name;
            this.belongingHost = belongingHost;
            this.group = group;
            this.status = status;
        }
    }
}