Source code snippets (examples)

This is a list of Alvin Alexander's source code snippets (simple source code examples).

Beginning Scala - error in Sum code example (missing arguments for method collect)

In the excellent book, Beginning Scala, there is an error in the an example named Sum that leads to an error message that begins, "missing arguments for method collect". Actually, this isn't an error, but it was a change in the Scala API after Scala 2.7.3, which is what the book was based on.

Here's a corrected version of the Sum class (Sum object, actually), courtesy of the URL shown, with two minor changes by me:

import scala.io._

/**
 * This is a corrected version of the Beginning Scala Sum class.
 * The book version of the class worked on Scala 2.7.3, but does not work
 * on newer versions of Scala (2.8, 2.9, etc.).
 */
object Sum {
  def main(args: Array[String]): Unit = {
    println("Enter numbers on separate lines and press ctrl-D (Unix/Mac) ctrl-C (Windows)")
    val input = Source.fromInputStream(System.in)
    val lines = input.getLines.toList
    println("Sum " + sum(lines))
    // note: you can use toSeq here as well
    //val lines = input.getLines.toSeq
  }

  def toInt(s: String): Option[Int] = {
    try {
      Some(Integer.parseInt(s))
    } catch {
        case e: NumberFormatException => None
    }
  }

  def sum(in: Seq[String]): Int = {
    val ints = in.flatMap(toInt(_))
    ints.foldLeft(0)((a, b) => a + b)
  }

}

In this corrected version, this line:

val lines = input.getLines.collect

has been changed to this line:

val lines = input.getLines.toList

As one of the notes on that web page shows, you can use this line as well:

val lines = input.getLines.toSeq

I tested both toList and toSeq with Scala 2.9.1, and both work fine, problem solved.

How to show the number of MongoDB open database connections (using the lsof command)

There are probably better ways to do this, but the only way I've found so far to see the number of open MongoDB database connections is to look at it from the Unix/Linux command line, using the lsof command:

$ sudo lsof | grep mongod | grep TCP
mongod    5733             Al    6u     IPv4 0x08761278       0t0       TCP *:28017 (LISTEN)
mongod    5733             Al    7u     IPv4 0x07c7eb98       0t0       TCP *:27017 (LISTEN)
mongod    5733             Al    9u     IPv4 0x08761688       0t0       TCP 192.168.1.103:27017->192.168.1.103:64752 (ESTABLISHED)
mongod    5733             Al   12u     IPv4 0x08761a98       0t0       TCP 192.168.1.103:27017->192.168.1.103:64754 (ESTABLISHED)
mongod    5733             Al   13u     IPv4 0x095fa748       0t0       TCP 192.168.1.103:27017->192.168.1.103:64770 (ESTABLISHED)
mongod    5733             Al   14u     IPv4 0x095f86c8       0t0       TCP 192.168.1.103:27017->192.168.1.103:64775 (ESTABLISHED)
mongod    5733             Al   17u     IPv4 0x08764748       0t0       TCP 192.168.1.103:27017->192.168.1.103:64777 (ESTABLISHED)

This shows that I currently have five connections open to the MongoDB port (27017) on my computer. In my case I'm connecting to MongoDB from a Scalatra server, and I'm using the MongoDB Casbah driver, but you'll see the same lsof TCP connections regardless of the client used (as long as they're connecting using TCP/IP).

Source code for a Java SwingWorker with ProgressBar example (SwingWorker background thread)

Here's the source code for a Java SwingWorker with ProgressBar example from Sun:

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
public class ProgressBarDemo extends JPanel implements ActionListener,
    PropertyChangeListener {

  private JProgressBar progressBar;
  private JButton startButton;
  private JTextArea taskOutput;
  private Task task;

  class Task extends SwingWorker<Void, Void> {
    /*
     * Main task. Executed in background thread.
     */
    @Override
    public Void doInBackground() {
      Random random = new Random();
      int progress = 0;
      // Initialize progress property.
      setProgress(0);
      while (progress < 100) {
        // Sleep for up to one second.
        try {
          Thread.sleep(random.nextInt(1000));
        } catch (InterruptedException ignore) {
        }
        // Make random progress.
        progress += random.nextInt(10);
        setProgress(Math.min(progress, 100));
      }
      return null;
    }

    /*
     * Executed in event dispatching thread
     */
    @Override
    public void done() {
      Toolkit.getDefaultToolkit().beep();
      startButton.setEnabled(true);
      setCursor(null); // turn off the wait cursor
      taskOutput.append("Done!\n");
    }
  }

  public ProgressBarDemo() {
    super(new BorderLayout());

    // Create the demo's UI.
    startButton = new JButton("Start");
    startButton.setActionCommand("start");
    startButton.addActionListener(this);

    progressBar = new JProgressBar(0, 100);
    progressBar.setValue(0);
    progressBar.setStringPainted(true);

    taskOutput = new JTextArea(5, 20);
    taskOutput.setMargin(new Insets(5, 5, 5, 5));
    taskOutput.setEditable(false);

    JPanel panel = new JPanel();
    panel.add(startButton);
    panel.add(progressBar);

    add(panel, BorderLayout.PAGE_START);
    add(new JScrollPane(taskOutput), BorderLayout.CENTER);
    setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

  }

  /**
   * Invoked when the user presses the start button.
   */
  public void actionPerformed(ActionEvent evt) {
    startButton.setEnabled(false);
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    // Instances of javax.swing.SwingWorker are not reusuable, so
    // we create new instances as needed.
    task = new Task();
    task.addPropertyChangeListener(this);
    task.execute();
  }

  /**
   * Invoked when task's progress property changes.
   */
  public void propertyChange(PropertyChangeEvent evt) {
    if ("progress" == evt.getPropertyName()) {
      int progress = (Integer) evt.getNewValue();
      progressBar.setValue(progress);
      taskOutput.append(String.format("Completed %d%% of task.\n", task
          .getProgress()));
    }
  }

  /**
   * Create the GUI and show it. As with all GUI code, this must run on the
   * event-dispatching thread.
   */
  private static void createAndShowGUI() {
    // Create and set up the window.
    JFrame frame = new JFrame("ProgressBarDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Create and set up the content pane.
    JComponent newContentPane = new ProgressBarDemo();
    newContentPane.setOpaque(true); // content panes must be opaque
    frame.setContentPane(newContentPane);

    // Display the window.
    frame.pack();
    frame.setVisible(true);
  }

  public static void main(String[] args) {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}

How to set an Apache HttpClient timeout value

How to set a timeout on an Apache HttpClient:

HttpClient client = new DefaultHttpClient();
client.getParams().setParameter("http.socket.timeout", new Integer(10*1000));

I like to make my code easier to read, so I use the "10*1000" there to make it easier to read that I want a ten-second timeout.

From a MongoDB collection to Scala object array through Gson to JSON

I used the following code to convert an array of Scala objects on the server into a JSON string that I could return back to the client. So it's going from a MongoDB collection to an array of Scala objects through Gson to become a JSON string.

/**
 * Return a list of all stored sticky notes as a JSON string.
 */
get("/getStickyNotes") {
  var notes = ArrayBuffer[StickyNote]()
  val coll = getMongoDbCollection
  val dbObjects = coll.find
  for (dbObject <- dbObjects) {
    notes += convertDbObjectToStickyNote(dbObject)
  }
  // return array as json
  (new Gson).toJsonTree(notes.toArray)
}

def convertDbObjectToStickyNote(o: MongoDBObject): StickyNote = {
  val content = o.getAs[String]("content")
  val windowTitle = o.getAs[String]("windowTitle")
  val fontSizeIncrement = o.getAs[Int]("fontSizeIncrement")
  return StickyNote(content.get, windowTitle.get, fontSizeIncrement.get)
}

A few notes:

  • The actual code is longer than this; I trimmed it down to make it easier to read here.
  • I used gson.toJsonTree in this code, but I may have been able to use just gson.toJson. I started using toJsonTree because of an unrelated problem.
  • If I was a cooler Scala programmer I'd probably use a collection method like flatMap instead of a for loop to create the notes object form dbObjects.
  • Notice the need to use .get when I return the StickyNote in the second to last line of code. That's because I'm dealing with Some references.

MongoDB drop collection examples (using the mongo command line)

I accidentally created some MongoDB collections within my database named "stickynotes" that I didn't want. All I wanted was a collection named notes, but I was fooling around and accidentally created some other collections. Here's how I deleted those collections using the mongo command line. (My commands are shown in bold.)

> use stickynotes
switched to db stickynotes

> show collections
notes
stickynotes
stickynotes.notes
system.indexes

> db.stickynotes.drop()
true

> show collections
notes
stickynotes.notes
system.indexes

> db.stickynotes.notes.drop()
true

> show collections
notes
system.indexes

Deserialize a JSON array using Gson, Scala, Scalatra, and a Scala case class

Here's an example of how I deserialize an array of objects encoded in JSON, in this case using Scalatra and Scala:

import scala.collection.JavaConversions._

/**
 * This method expects to receive Array[StickyNote].
 */
post("/saveStickyNote") {
  val json = params.get("STICKY_NOTE")
  val gson = new Gson
  try {

    // (1) convert the json string to an array of StickyNote
    val jsonString = json.get

    // (2) jsonString is actually a Some, need to use get() here (should also test for None)
    val stickyNotes = gson.fromJson(jsonString, classOf[Array[StickyNote]])

    // (3) do whatever you want with your object array
    for (stickyNote <- stickyNotes) {
      println("CONTENT: " + stickyNotes.content)
    }

  } catch {
    case e: Exception => e.printStackTrace
    case _ => println
  }
}

To get this to work, I've defined a StickyNote case class here on the server side, and Gson does a great job of converting properly formatted JSON into an array of StickyNote objects.

If you were using Gson with Java to deserialize a JSON array, your code would look very similar. The major change would be that your Java code in the gson.fromJson line would look something like this:

val stickyNotes = gson.fromJson(jsonString, StickyNote[].class)

I'm not sure what the exact syntax should be there, but I think that's right, or hopefully close enough to get you started if you're using Java.

Scala case classes, Gson, Json object deserialization, and Scalatra

I was able to get Gson to work with Scala and Scalatra very easily. Here's a sample Scalatra POST method where I receive a JSON string and convert it to a StickyNote case class object:

post("/saveStickyNote") {
  val json = params.get("STICKY_NOTE")
  val gson = new Gson
  try {
    // jsonString is actually a Some, need to use get() here
    val stickyNote = gson.fromJson(json.get, classOf[StickyNote])

    // i can now call methods on my stickyNote object
    println("CONTENT: " + stickyNote.content)

    // do whatever you need to with the stickyNote object ...
  } catch {
      case e: Exception => e.printStackTrace
      case _ => println
  }
}

Gson and Scala also work very easily with arrays of JSON objects, like this:

val notes = gson.fromJson(json.get, classOf[Array[StickyNote]])

I can share more information about my StickyNote object later, but it's just a basic Scala case class, nothing major.

How to start the Jetty server when using Scalatra with SBT

When working on a Scalatra project, this is how I start the Jetty server using SBT:

# (1) start sbt
$ sbt

# (2) start the jetty server at the sbt command line
> container:start

There is supposed to be a way to get this to be a "continuous compile", so you don't always have to stop and start Jetty, but I haven't been able to get that to work properly.

A simple way to center a JFrame (Java JFrame)

This is a simple way to center a JFrame in Java:

myFrame.setLocationRelativeTo(null);