/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.tools.refactoring;

// no blank line here - first specify Java imports:
import java.lang.reflect.*;
// blank line - next specify all the TopLink imports:
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.exceptions.*;
// another blank line
/**
 * <p><b>Purpose</b>: Describe the purpose of the Class.
 * <p><b>Responsibilities</b>:<ul>
 * <li> class responsibility
 * <li> class responsibility
 * </ul>
 *
 *  @author ABC
 *  @since TOPLink/Java 1.0
 */
// yet another blank line
public class CodingStandard {
// still another blank line
    /** Put one line comment describing the following variable */
    protected String giveDescriptiveNameToVariables;
    
    /** Put one line comment describing the following variable */
    protected String useTabsToIndentVariables;
    
    /** Put one line comment describing the following variable */
    protected String useSingleLineSpacingBetweenVariables;

    /** Put one line comment describing the following variable */
    protected String commentShouldBeJustBeforeVariable;

    /** Put one line comment describing the following variable */
    protected String useSpacingAfterAndBeforeClassOpenAndCloseBrackets;

    /** Put one line comment describing the following variable */
    protected String allVariablesAreProtected;
    
    protected String commentOnlyImportantVariables;
    // final blank line
    /**
     * First of all, we should not access variables directly in the methods. 
     * But if we do then always use this.attributeName notation.
     */ 
    public void accessingClassAttributes() 
    {

    }
    
    /**
     * A blank line should always be used in the following circumstances:
     *      - between logical sections inside a method - to improve readability
     *      - between the method comment and the method declaration
     */ 
    public void blankLines() 
    {
    
    }
    
    /**
     * Blank spaces should always be used in the following circumstances:
     *      - A keyword followed by a parenthesis should be separated by a space:
     *              while (true) {
     *                  ...
     *              }
     *
     *      - Note that a blank should not be used between a method name and its opening
     *        parenthesis. This helps to distinguish keywords from method calls.
     *
     *      - Blanks should appear after commas in argument lists.
     *
     *      - All binary operators should be separated from their operands by spaces.
     *
     *      - The expressions in a "for" statement should be separated by blanks. 
     *              for (expr1; expr2; expr3)
     *
     *      - Casts should be followed by a blank.
     *              (void) method((byte) aNum, (Object) x);
     *
     */
    public void blankSpaces() 
    {

    }
    
    /**
     * A boolean variable should always be prefixed with conjunctions like is, has, does, should, etc.
     * Examples: isNullAllowed, shouldMaintainCache, doesObjectExist, hasTables
     *
     * The get accessor for such variables should be the name of the variable itself and the set accessor
     * is the usual one
     *          Example isNullAllowed(), setIsNullAllowed(boolean value)
     *
     * With each boolean variable we should also provide two modifiers. 
     *          Example 
     *              allowNull()
     *              {
     *                  setIsNullAllowed(true);
     *              }
     *              
     *              dontAllowNull()
     *              {
     *                  setIsNullAllowed(true);
     *              }                   
     */ 
    public void booleanVariable() 
    {

    }
    
    /**
     * It's a good idea to declare all the varibles at the beginning of a code block as
     * variables defined in the middle of the block can be confusing.
     */ 
    public void declarationsInTheMethod(Session firstArgument, String secondArgument)
    { /* Place the starting bracket on a new line */
      /* One declaration per line is recommended since it encourages commenting */
        int level,      // indentation level
            size;       // size of table
        /* New declaration should start on new line */
        float foo,
              bar;
        /* Give one line space before coding method body */
        methodBody();       
    }
    
    /**
     * Never break for-statements into multiple lines.
     * Break down the components of the for-statement into multiple lines if necessary.
     */  
    public void forStatements()
    { 
        /* WRONG 
         * The following loop puts too much information on the same line:
         *
         * for (Enumeration mappings = getQuery().getDescriptor().getMappings().elements(); mappings.hasMoreElements(); ) {
         *      some statements;
         *  }
         *
         */
    
        /* RIGHT
         *
         *  Vector mappings = getQuery().getDescriptor().getMappings();
         *  for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements(); ) {
         *      some statements;
         *  }
         *
         */
    }
    
    /**
     * Always use the braces {}. This makes the statement more clear and prevents
     * some sloppy bugs (i.e if you add a second line).
     * WRONG:
     * if (condition)
     *      doStuff();
     * else
     *      doOtherStuff();
     */  
    public void ifElseStatements()
    {
        boolean condition = true;
    
        if (condition) {
            //statements
        }
    
        if (condition) {
            //statements
        } else {
            //statements
        }

        if (condition) {
            //statements
        } else if (condition) {
            //statements
        } else {
            //statements
        }
    }
    
    /**
     * Avoid long statements. Maintainence is a nightmare.
     */ 
    public void longStatements()
    {
        /*
         * WRONG:
         * setTableDefinition(getTableDefinitionNamed(((DatabaseTable)getMapping().getDescriptor().getTables().firstElement()).getName()));
         *
         * RIGHT:
         * The right approach to this statement would be to break it up into smaller statements. This would mean few more
         * lines and local variables, but will be easy to understand
         *
         * DatabaseTable table = (DatabaseTable)getMapping().getDescriptor().getTables().firstElement();
         * String tableName = table.getName();
         * TableDefinition tableDefinition = getTableDefinitionNamed(tableName);
         * setTableDefinition(tableDefinition);
         */
    }
    
    /**
     * NOTE:
     * A compound statement is a statement that contains several other statements enclosed in braces "{}".
     *  The enclosed statements should be indented one more level than the compound statement.
     *
     *  The opening left brace should be at the end of the line beginning the compound statement,
     *  and the closing right brace should begin a line and be indented to match the beginning of the 
     *  compound statement.
     *
     *  Braces are used around all statements, even single statements, when they are part of a control 
     *  structure, such as an "if-else" or "for" statement. This makes it easier to add or delete 
     *  statements without accidentally introducing bugs due to forgetting to add braces.
     */  
    public void methodBody()
    {
        longStatements();
        ifElseStatements();
        forStatements();
        whileStatements();
        tryCatchStatements();
    }
    
    /**
     * INTERNAL:
     * Give a full description of the user callable method. Make sure it is javadoc compatible.
     * - blank line -
     * @param argument1 This is optional, give full description only if neccessary.
     * @exception InvocationTargetException This is optional, give full description only if neccessary.
     * @return String This is optional, give full description only if neccessary.
     */
    public String methodCommentsForNonAPI(String argument1, String argument2)
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
    {
        String descriptiveVariable = "The variable should be descriptive enough to convey its meaning.";
    
        return descriptiveVariable;
    }
    
    /**
     * PUBLIC:
     * Give a full description of the user callable method. Make sure it is javadoc compatible.
     *  - blank line -
     * @param argument1 This is optional, give full description only if neccessary.
     * @exception InvocationTargetException This is optional, give full description only if neccessary.
     * @return String This is optional, give full description only if neccessary.
     */
    public String methodCommentsForUserAPI(String argument1, String argument2)
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
    {
        String descriptiveVariable = "The variable should be descriptive enough to convey its meaning.";
    
        return descriptiveVariable;
    }
    
    /**
     * method comments
     */
    public void methodDeclarationIsLong(String argument1, String argument2)
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
    {
        // do something
    }
    
    /**
     * method Comments
     */
    public void methodDeclarationIsReallyLong(
            String argument1,
            String argument2,
            String argument3,
            String ifYouHaveMoreArgumentsThenCheckYourMethod)
        throws
            IllegalAccessException,
            IllegalArgumentException,
            InvocationTargetException
    {
        // do something
    }
    
    /**
     * Instead of prefixing the parameter "useTabsToIndentVariable" with an article (e.g. a, an, the)
     * and then assigning to the class attribute we can do the following assignment.
     *
     * NOTE:
     * Prefixing parameters in non accessor methods makes sense because we can differentiate between
     * local variables and passed parameters.
     */
    public void setAccessor(String useTabsToIndentVariable)
    {
        this.useTabsToIndentVariables = useTabsToIndentVariable;    
    }
    
    /**
     * TopLink exceptions are all runtime exceptions - so they do not have to be caught.
     * If the method throws the exception then it must be declared in the "throws" clause.
     * The one exception is if a runtime exception is caught for cleanup purposes,
     * then it should not be re-thrown.
     * A method that calls a method that throws a TopLink exception should not also throw it,
     * the exception to this is database and optimistic lock exceptions which must always
     * be thrown up to the user callable methods.
     */  
    public void toplinkExceptions () throws DatabaseException, QueryException
    {
        /*
        Cursor cursor = prepareCuror();
        try {
            if (cursor.isEmpty()) {
                throw new QueryException("This must not be empty because ...", getQuery());
            }
            doStuff(cursor);    
        } catch (RuntimeException exception) {
            cursor.close();
            throw exception;
        }   
        */  
    }
    
    public void tryCatchStatements ()
    {
        /*
        try {
            statements;
        } catch (Exception exception) {
            statements;
        }   
        */  
    }
    
    public void whileStatements ()
    {
    /*
     * A while statement should have the following form:
     *              while (condition) {
     *                  statement;
     *              }
     *
     * An empty while statment should have the following form:
     *              while (condition);
     */
    }
}
