Local Server

Download Sample Viewer

Description

This sample shows how to manage the local server and how to start and stop local services.

Code snippet


    // initialize or shutdown the local server asynchronously
    LocalServer.getInstance().initializeAsync();
    LocalServer.getInstance().shutdownAsync();

    // start or stop the service asynchronously
    service.startAsync();
    service.stopAsync();
  

Sample Code

/* Copyright 2014 Esri

All rights reserved under the copyright laws of the United States
and applicable international laws, treaties, and conventions.

You may freely redistribute and use this sample code, with or
without modification, provided you include the original copyright
notice and use restrictions.

See the use restrictions.*/
package com.esri.client.samples.localserver;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.esri.client.local.GPServiceType;
import com.esri.client.local.LocalFeatureService;
import com.esri.client.local.LocalGeocodeService;
import com.esri.client.local.LocalGeoprocessingService;
import com.esri.client.local.LocalMapService;
import com.esri.client.local.LocalServer;
import com.esri.client.local.LocalServerStatus;
import com.esri.client.local.LocalService;
import com.esri.client.local.LocalServiceStartCompleteEvent;
import com.esri.client.local.LocalServiceStartCompleteListener;
import com.esri.client.local.LocalServiceStatus;
import com.esri.client.local.LocalServiceStopCompleteEvent;
import com.esri.client.local.LocalServiceStopCompleteListener;
import com.esri.client.local.ServerLifetimeEvent;
import com.esri.client.local.ServerLifetimeListener;
import com.esri.client.local.ServerMessageEvent;
import com.esri.client.local.ServerMessageListener;
import com.esri.toolkit.utilities.BrowserLauncher;
import com.esri.runtime.ArcGISRuntime;

public class LocalServerApp {

  // Swing components
  private JTextArea textArea;
  private JComboBox<ServiceType> comboBox;
  private JButton btnStartService;
  private JButton btnStopService;
  private JButton btnStopLocalServer;
  private JButton btnStartLocalServer;
  private JButton listButton;

  // keep track of the running services
  private LocalService[] localServices = new LocalService[ServiceType.values().length];
  private ArrayList<String> runningServices = new ArrayList<>();
  private ArrayList<String> runningServicesUrl = new ArrayList<>();
  private JList<String> listServices;

  // UI constants
  private static final int SPACING = 5;
  private static final int BUTTON_HEIGHT = 30;
  private static final int BUTTON_WIDTH = 120;
  private static String FSP = System.getProperty("file.separator");

  /**
   * Constructor.
   */
  public LocalServerApp() {
    if (LocalServer.getInstance().isInitialized()) {
      LocalServer.getInstance().shutdown();
    }
  }

  // ------------------------------------------------------------------------
  // Core functionality
  // ------------------------------------------------------------------------
  /**
   * A listener class which starts and stops the LocalServer
   * asynchronously.
   */
  private class StartStopLocalServer implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {

      if (e.getActionCommand().equals("start")) {
        writeToTextArea("Starting Local Server ...");
        // initialize the local server asynchronously
        LocalServer.getInstance().initializeAsync();
      } else if (e.getActionCommand().equals("stop")) {
        writeToTextArea("Stopping Local Server ...");
        // shut down the local server asynchronously
        LocalServer.getInstance().shutdownAsync();
        // manually clear our list of services
        for (int i = 0; i < localServices.length; i++) {
          localServices[i] = null;
        }
      }
    }
  }

  /**
   * A listener class which starts a service.
   */
  private class StartService implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {

      // which service are we starting? get from the comboBox
      ServiceType serviceType = (ServiceType) comboBox.getSelectedItem();
      writeToTextArea("Starting " + serviceType + " ...");

      // start the service, with data path and type depending on the service type
      switch (serviceType) {
        case MAP:
          LocalMapService localMapService = new LocalMapService(
              getPathSampleData() + "mpks" + FSP + "USCitiesStates_Lambert_Conformal_Conic.mpk");
          localServices[0] = startStopLocalService(localMapService, true, serviceType);
          break;
        case GEOCODE:
          LocalGeocodeService localGeocodeService = new LocalGeocodeService(
              getPathSampleData() + "locators" + FSP + "SanFrancisco" + FSP + "SanFranciscoLocator.gcpk", null);
          localServices[1] = startStopLocalService(localGeocodeService, true, serviceType);
          break;
        case FEATURE:
          LocalFeatureService localFeatureService = new LocalFeatureService(
              getPathSampleData() + "mpks" + FSP + "PointsofInterest.mpk");
          localServices[2] = startStopLocalService(localFeatureService, true, serviceType);
          break;
        case GP:
          LocalGeoprocessingService localGPService = new LocalGeoprocessingService(
              getPathSampleData() + "gpks" + FSP + "ClipFeatures" + FSP + "ClipFeatures.gpk");
          localGPService.setServiceType(GPServiceType.SUBMIT_JOB);
          localServices[3] = startStopLocalService(localGPService, true, serviceType);
          break;
      }
    }
  }

  /**
   * A listener class which stops a service.
   */
  private class StopService implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
      ServiceType serviceType = (ServiceType) comboBox.getSelectedItem();
      // stop the service (this relies on comboBox/localServices index-matching)
      startStopLocalService(localServices[comboBox.getSelectedIndex()], false, serviceType);
      localServices[comboBox.getSelectedIndex()] = null;
      updateUI();
      updateList();
    }
  }

  /**
   * Method to start or stop a service asynchronously. Attaches a listener to the
   * service if the service is not started.
   *
   * @param service - the service to start
   * @param isStart - whether we are starting or stopping a service
   * @param serviceType - the service type
   * @return service - the local service we have started or stopped
   */
  private LocalService startStopLocalService(LocalService service, boolean isStart, final ServiceType serviceType) {

    // add a listener if our service is not started
    if (service.getStatus() != LocalServiceStatus.STARTED){

      service.addLocalServiceStartCompleteListener(new LocalServiceStartCompleteListener() {

        @Override
        public void localServiceStartComplete(LocalServiceStartCompleteEvent e) {
          writeToTextArea("Local " + serviceType + " " + e.getService().getStatus().toString());
          writeToTextArea("Local " + serviceType + " - URL: " + e.getUrl());
          updateUI();
          updateList();
        }
      });

      service.addLocalServiceStopCompleteListener(new LocalServiceStopCompleteListener() {

        @Override
        public void localServiceStopComplete(LocalServiceStopCompleteEvent e) {
          writeToTextArea("Local " + serviceType + " " + e.getService().getStatus().toString());
          updateUI();
          updateList();
        }
      });

    }
    // start or stop the service asynchronously
    if (isStart)
      service.startAsync();
    else
      service.stopAsync();

    return service;
  }

  // ------------------------------------------------------------------------
  // Public method
  // ------------------------------------------------------------------------
  /**
   * Creates the UI for this application, including the buttons, combo box,
   * text area, and list.
   * @return contentPane
   */
  public JComponent createUI() {

    // content pane
    JComponent contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(SPACING, SPACING, SPACING, SPACING));
    contentPane.setLayout(new BorderLayout(0, 0));

    // top panel
    JPanel topPanel = new JPanel();
    topPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    contentPane.add(topPanel, BorderLayout.NORTH);

    // server buttons and panel
    JPanel serverPanel = new JPanel();
    serverPanel.setLayout(new GridLayout(2, 1, SPACING, SPACING));
    serverPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    serverPanel.setBorder(BorderFactory.createTitledBorder(
        "Local Server controls"));
    Dimension preferredSize = new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT);
    btnStartLocalServer = new JButton("Start Local Server");
    btnStartLocalServer.setActionCommand("start");
    btnStartLocalServer.setPreferredSize(preferredSize);
    btnStartLocalServer.addActionListener(new StartStopLocalServer());
    btnStopLocalServer = new JButton("Stop Local Server");
    btnStopLocalServer.setActionCommand("stop");
    btnStopLocalServer.setPreferredSize(preferredSize);
    btnStopLocalServer.setEnabled(false);
    btnStopLocalServer.addActionListener(new StartStopLocalServer());
    serverPanel.add(btnStartLocalServer);
    serverPanel.add(btnStopLocalServer);

    // local services buttons
    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new GridLayout(1, 2, SPACING, SPACING));
    buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    btnStartService = new JButton("Start Service");
    btnStartService.setPreferredSize(preferredSize);
    btnStartService.addActionListener(new StartService());
    btnStopService = new JButton("Stop Service");
    btnStopService.setPreferredSize(preferredSize);
    btnStopService.addActionListener(new StopService());
    btnStopService.setEnabled(false);
    buttonPanel.add(btnStartService);
    buttonPanel.add(btnStopService);

    // local services panel for combo box and buttons
    JPanel servicesPanel = new JPanel();
    servicesPanel.setLayout(new BoxLayout(servicesPanel, BoxLayout.Y_AXIS));
    servicesPanel.setBorder(BorderFactory.createTitledBorder(
        "Local Services controls"));
    comboBox = new JComboBox<>();
    comboBox.setModel(new DefaultComboBoxModel<>(ServiceType.values()));
    comboBox.setMinimumSize(new Dimension(300, BUTTON_HEIGHT));
    comboBox.setPreferredSize(new Dimension(400, BUTTON_HEIGHT));
    comboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
    ComboListener comboListener = new ComboListener();
    comboBox.addActionListener(comboListener);
    servicesPanel.add(comboBox);
    servicesPanel.add(Box.createRigidArea(new Dimension(SPACING, SPACING)));
    servicesPanel.add(buttonPanel);

    topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
    topPanel.add(serverPanel);
    topPanel.add(servicesPanel);

    JPanel mainPanel = new JPanel();
    contentPane.add(mainPanel, BorderLayout.CENTER);
    mainPanel.setLayout(new BorderLayout(SPACING, 0));

    // text area for text output
    textArea = new JTextArea();
    textArea.setEditable(false);
    JScrollPane scrollPane = new JScrollPane(textArea);
    scrollPane.setAutoscrolls(true);
    mainPanel.add(scrollPane, BorderLayout.CENTER);

    // panel to display list of running services
    JPanel listPanel = new JPanel();
    listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
    listPanel.setBorder(BorderFactory.createTitledBorder(
        "List of running services"));
    listServices = new JList<>(); // the list
    listServices.setFont(new Font("Dialog", 1 , 12));
    listServices.setVisibleRowCount(6);
    listServices.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    listButton = new JButton("   Go to URL   "); // button to open URL
    listButton.addActionListener(new OpenURL());
    listButton.setAlignmentX(Component.LEFT_ALIGNMENT);
    listButton.setEnabled(false);
    listServices.addListSelectionListener(new ListSelectionListener() {
      @Override
      public void valueChanged(ListSelectionEvent e) {
        if (!listServices.isSelectionEmpty()) {
          listButton.setEnabled(true);
        } else {
          listButton.setEnabled(false);
        }
      }
    });
    JScrollPane listScroll = new JScrollPane(listServices);
    listScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
    listPanel.add(listScroll);
    listPanel.add(Box.createRigidArea(new Dimension(0, SPACING)));
    listPanel.add(listButton);
    mainPanel.add(listPanel, BorderLayout.SOUTH);

    // keep track of what the Local Server status is
    LocalServer.getInstance().addServerLifetimeListener(new ServerLifetimeListener() {

      @Override
      public void serverLifetimeShutdown(ServerLifetimeEvent e) {
        writeToTextArea("Local Server status: " + LocalServer.getInstance().getStatus().toString());
        btnStartService.setEnabled(true);
        btnStopLocalServer.setEnabled(false);
        btnStartLocalServer.setEnabled(true);
        updateUI();
        updateList();
      }

      @Override
      public void serverLifetimeInitialized(ServerLifetimeEvent e) {
        writeToTextArea("Local Server status: " + LocalServer.getInstance().getStatus().toString());
        if (LocalServer.getInstance().getStatus().equals(LocalServerStatus.INITIALIZED)) {
          writeToTextArea("Local Server install location: \n" +
              ArcGISRuntime.getInstallDirectory().toString() );
          btnStopLocalServer.setEnabled(true);
          btnStartLocalServer.setEnabled(false);
          updateUI();
        }
      }
    });

    // capture messages from the Local Server
    LocalServer.getInstance().addServerMessageListener(new ServerMessageListener() {

      @Override
      public void handleMessage(ServerMessageEvent e) {
        writeToTextArea(e.getMessage());
      }
    });

    return contentPane;
  }

  enum ServiceType {
    MAP("Map Service"),
    GEOCODE("Geocode Service"),
    FEATURE("Feature Service"),
    GP("Geoprocessing Service");

    private String displayName;

    ServiceType(String displayName) {
      this.displayName = displayName;
    }

    @Override
    public String toString() {
      return displayName;
    }
  }

  // ------------------------------------------------------------------------
  // Static methods
  // ------------------------------------------------------------------------
  /**
   * Launch the application.
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          LocalServerApp app = new LocalServerApp();

          // create the UI, including the map, for the application
          JFrame appWindow = app.createWindow();
          appWindow.add(app.createUI());
          appWindow.setVisible(true);
        } catch (Exception e) {
          // on any error, display the stack trace
          e.printStackTrace();
        }
      }
    });
  }

  // ------------------------------------------------------------------------
  // Private methods
  // ------------------------------------------------------------------------
  private void updateUI() {

    int item = comboBox.getSelectedIndex();

    if (localServices[item] != null) {

      if (localServices[item].getStatus() == LocalServiceStatus.STOPPED) {
        // ATM can only start one service of one type at once
        btnStopService.setEnabled(false);
        btnStartService.setEnabled(true);
      } else {
        btnStartService.setEnabled(false);
        btnStopService.setEnabled(true);
      }
    } else {
      btnStartService.setEnabled(true);
      btnStopService.setEnabled(false);
    }
  }

  private void updateList() {
    syncList();
    listServices.setListData(runningServices.toArray(new String[0]));
  }

  private void writeToTextArea(String text) {
    textArea.append(text + "\n");
    textArea.scrollRectToVisible(new Rectangle(0, textArea.getHeight(), 1, 1));
  }

  private class ComboListener implements ActionListener  {

    @Override
    public void actionPerformed(ActionEvent e) {
      updateUI();
    }
  }

  private class OpenURL implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent event) {
      String url = runningServicesUrl.get(listServices.getSelectedIndex());
      BrowserLauncher.openURL(url);
    }
  }

  private void syncList() {
    runningServices.clear();
    runningServicesUrl.clear();
    for (LocalService service : localServices) {
      if (service != null) {
        String url = null;
        if (service instanceof LocalMapService) {
          url = ((LocalMapService)service).getUrlMapService();
          runningServices.add("Local Map Service - " + url);
          runningServicesUrl.add(url);

          // LocalFeatureService is a type of LocalMapService
          if (service instanceof LocalFeatureService) {
            url = ((LocalFeatureService)service).getUrlFeatureService();
            runningServices.add("Local Feature Service - " + url);
            runningServicesUrl.add(url);
          }
        } else if (service instanceof LocalGeocodeService) {
          url = ((LocalGeocodeService)service).getUrlGeocodeService();
          runningServices.add("Local Geocode Service - " + url);
          runningServicesUrl.add(url);
        } else if (service instanceof LocalGeoprocessingService) {
          url = ((LocalGeoprocessingService)service).getUrlGeoprocessingService();
          runningServices.add("Local Geoprocessing Service - " + url);
          runningServicesUrl.add(url);
        }
      }
    }
  }

  /**
   * Creates a window.
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame("Local Server Application");
    window.setBounds(100, 100, 1000, 700);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout(0, 0));
    return window;
  }

  private String getPathSampleData() {
    String dataPath = null;
    String javaPath = ArcGISRuntime.getInstallDirectory();
    if (javaPath != null) {
      if (!(javaPath.endsWith("/") || javaPath.endsWith("\\"))){
        javaPath += FSP;
      }
      dataPath = javaPath + "sdk" + FSP + "samples" + FSP + "data" + FSP;
    }
    File dataFile = new File(dataPath);
    if (!dataFile.exists()) { 
      dataPath = ".." + FSP + "data" + FSP;
    }
    return dataPath;
  }
}
Feedback on this topic?