Rosettas‎ > ‎

Java


// Copyright (c) 2007 Art & Logic, Inc. All Rights Reserved.
// $Id: Rosetta.java,v 1.1 2010/01/26 22:08:56 bporter Exp $

// Above: [sf02], [sf03]


// a note on the stuff inside the square brackets:
// Each of the codes inside brackets is a reference to the rule(s) in the
// Style Guide that's being illustrated, as follows:
// [sf##] - StyleGuide/SourceFiles
// [cas##] - StyleGuide/ClassesAndStructures
// [nr##] - StyleGuide/NamingRules
// [cg##] - StyleGuide/Commenting
// [fmt##] - StyleGuide/Formatting

// Throughout: [fmt01]; all indentation done with space characters (0x20),
// three spaces per logical tab stop.


package com.ArtLogic.Rosetta;


// [sf05]
import java.io.File;
import java.lang.String;

import com.ArtLogic.util.AlTypes;


// [sf07], only one class declared/defined in this source file [redundant in Java]

// [cg02], comments useful to programmers who will use (but not necessarily
// maintain) this class are separated out into the header file, not in the
// implementation file. [redundant in Java]
/**
 * @class ARosetta
 * @brief Simple, but meaningless class to demonstrate Art & Logic programming
 * style conventions as they are applied to the various programming languages
 * we use. In several places, you're asked to imagine a block of useful code
 * to avoid distracting you from the issues of formatting (etc) that are being
 * demonstrated.
 *
 * As you've already seen above, the thing about to be shown in this file is
 * called out in comments using the A&L-style markup '!!!'
 */
// [nr11], [nr18] class names prefixed with "A"
public class ARosetta
{
   // [nr25] the 'q' prefix indicates that we are controlling conditional
   // compilation [...or in Java, conditional execution]
   private static final boolean qVerbose = true;

   // [cas01] public member functions/methods listed first

   // [nr08] new non-class types (enumerations, data structures, etc) are
   // named with MixedCase and no special prefix
   public enum EnumName
   {
      // [nr23] identifiers specifying constants for the program are always
      // prefixed with a lowercase 'k'.
      kSomeConstant,
      kSomeOtherConstant;
   };

   /**
    * Construct and initialize the Rosetta object.
    * @param fileName The file to use as our data source
    */
   public ARosetta(String fileName)
   {
      fFileName = fileName;
      fInputFile = new File(fFileName);
      fProcessResult = 0;
   }

   /**
    * [nr07] In Java, class methods (other than a class' constructor) begin with 
    * a lowercase letter, and additional words in the method name are capitalized.
    */
   public boolean memberFunctionWithMultipleWords()
   {
     boolean ok = true;

// [fmt02] -- labels used as the target of a break or continue are 
// placed in column zero.
blockOfCode:
{
     // [fmt08] -- formatting  of a for() loop.
      for (int i = 0; i < kSomeConstant; ++i)
      {
         for (int j = 0; j < kSomeOtherConstant; ++j)
         {
            // [fmt02] -- preprocessor directives
            if(qVerbose)
            {
               System.out.printf("testing: %d, %d\n", i, j);
            }
            // [nr07] -- Calls to member functions of the current object are
            // made through an explicit "this." 
            ok = this.test(i, j);
            if (!ok)
            {
               System.out.printf("Fatal error testing: %d, %d\n", i, j);
               break blockOfCode;
            }
         }
      }
      return true;
}  // end blockOfCode:

   // cleanup code here...
      return false;
   }

   /**
    * !!! Here's how we handle very long lines (i.e., longer than 79
    * characters)
    */
   public boolean longLineWrapping()
   {
      // [fmt03] -- source lines should be less than 80 characters long.
      // [fmt04] -- break lines at the most logical point
   //       1         2         3         4         5         6         7
   //34567890123456789012345678901234567890123456789012345678901234567890123456789
      retval = FunctionWithManyArguments(longArgumentName1, longArgumentName2,
       longArgumentName3, longArgumentName4);

      // alternative format #1
      retval = FunctionWithManyArguments(longArgumentName1,
       longArgumentName2,
       longArgumentName3,
       longArgumentName4);

      // alternative format #2
      retval = FunctionWithManyArguments(
       longArgumentName1,
       longArgumentName2,
       longArgumentName3,
       longArgumentName4);

      // [fmt05] -- prefer to break after a comma
      retval = anObject.someUsefulFunction(x.leftMargin() + x.rightMargin(),
       x.topMargin() + x.bottomMargin() - 1);

      // [fmt05] -- if that's not possible, break after an operator
      retval = anObject.SomeUsefulFunction(x.leftMargin() + x.rightMargin() +
       anObject.horizontalPadding(), x.topMargin() + x.bottomMargin() - 1);
   }

   /**
    * !!! Loop formatting
    */
   public void loops()
   {
      // [fmt08] -- for() loop; note the pre-incremented form of the loop control
      for (int i = 0; i < kSomeConstant; ++i)
      {
         // loop code here...
      }

      // [fmt09]
      while (someBoolean)
      {
         // useful code...
      }

      // [fmt09] -- while loop with an empty body makes the emptiness explicit
      while (this.someFuncReturningBool())
      {
         // intentionally empty...
      }

      // [fmt10] -- do/while loop.
      // [fmt18] -- exception to the bracing rule saying that braces should
      // always be on a line by themselves
      do
      {
         // loop code here..
      } while (someBoolean);
   }

   // [cas01] Protected member functions declared after public

   /**
    * [nr03] parameters passed to functions are named using lowerCamelCase
    */
   protected boolean test(int firstVal, int secondVal)
   {
      boolean retval = true;
      // [fmt07] -- if/else formatting
      if (firstVal < secondVal)
      {
         // [cg06] -- use '$$$' as a marker to indicate a request that the
         // following block of code be reviewed before a change is considered
         // complete
         // $$$ before
         // this->Process(secondVal);
         // $$$ after
         // Shouldn't this be processing the first value in this case?
         this.process(firstVal);
         // $$$ end
      }
      else if (secondVal > kSomeConstant)
      {
         this.process(secondVal);
      }
      else
      {
         // [fmt18] -- use curly braces even in cases where the language doesn't
         // require it to prevent maintenance errors.
         retval = false;
      }

      return retval;
   }

   // [cas01]  Private member function declared after protected

   /**
    * Useful function to process something or other.
    */
   private void process(int val)
   {
      // [cg05] -- use '!!!' as a marker to indicate a section of code that
      // requires attention
      // !!!... removing old hardcoded value
      // fProcessResult = 131;
      // ...!!!
      int result = val;
      while (--val)
      {
         result *= val;
      }
      this.fProcessResult = result;
   }

   /**
    * Demonstrating the formatting of a switch statement.
    */
   private void decide(char midiEventType)
   {
      // [fmt11] -- switch/case formatting.
      switch (midiEventType)
      {
         // comments precede the case
         case kNoteOn:
         this.noteOn(now);
         if (duration > 0)
         {
            this.noteOff(now + duration);
         }
         break;

         case kNoteOff:
         this.noteOff(now);
         break;

         case  kPolyAfter:
         after = channelValue;
         // [fmt35] include, but comment out the break when falling through intentionally.
         // break;

         case kChannelAfter:
         this.afterTouch(after);
         break;

         // [fmt36] no need to include a commented out break when falling through an empty case
         case kPitchbend:
                           // blank line...

         // [fmt12] -- switch statements should always have a default case.
         default:
         assert(false);
         this.logError("Unsupported event type!");
         break;
      }
   }

   // [cas02] member variables declared in the same order: public
   // (avoid in most languages), protected, private.


   // [nr04], [nr19] Member variables are prefixed with a lowercase 'f', followed
   // by an  uppercase letter.
   public String    fFileName;

   protected File fInputFile;

   private int fProcessResult;


}