/*
 * Copyright 2002-2009 the original author or authors.
 *
 * 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.springframework.expression.spel.ast;

import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;

/**
 * Implements the multiply operator. Conversions and promotions:
 * http://java.sun.com/docs/books/jls/third_edition/html/conversions.html Section 5.6.2:
 *
 * <p>If any of the operands is of a reference type, unboxing conversion (5.1.8) is performed. Then:<br>
 * If either operand is of type double, the other is converted to double.<br>
 * Otherwise, if either operand is of type float, the other is converted to float.<br>
 * Otherwise, if either operand is of type long, the other is converted to long.<br>
 * Otherwise, both operands are converted to type int.
 *
 * <p>
 *
 * @author Andy Clement
 * @since 3.0
 */
public class OpMultiply extends Operator {


	public OpMultiply(int pos, SpelNodeImpl... operands) {
		super("*", pos, operands);
	}

	/**
	 * Implements multiply directly here for some types of operand, otherwise delegates to any registered overloader for
	 * types it does not recognize. Supported types here are:
	 * <ul>
	 * <li>integers
	 * <li>doubles
	 * <li>string and int ('abc' * 2 == 'abcabc')
	 * </ul>
	 */
	@Override
	public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
		Object operandOne = getLeftOperand().getValueInternal(state).getValue();
		Object operandTwo = getRightOperand().getValueInternal(state).getValue();
		if (operandOne instanceof Number && operandTwo instanceof Number) {
			Number leftNumber = (Number) operandOne;
			Number rightNumber = (Number) operandTwo;
			if (leftNumber instanceof Double || rightNumber instanceof Double) {
				return new TypedValue(leftNumber.doubleValue() * rightNumber.doubleValue());
			} else if (leftNumber instanceof Long || rightNumber instanceof Long) {
				return new TypedValue(leftNumber.longValue() * rightNumber.longValue());
			} else {
				return new TypedValue(leftNumber.intValue() * rightNumber.intValue());
			}
		} else if (operandOne instanceof String && operandTwo instanceof Integer) {
			int repeats = (Integer) operandTwo;
			StringBuilder result = new StringBuilder();
			for (int i = 0; i < repeats; i++) {
				result.append(operandOne);
			}
			return new TypedValue(result.toString());
		}
		return state.operate(Operation.MULTIPLY, operandOne, operandTwo);
	}

}

@@ -20,10 +20,10 @@
 2-20
-09
+12
  the
@@ -906,24 +906,31 @@
 nts the 
+%7B@code 
 multiply
  operato
@@ -921,16 +921,17 @@
 multiply
+%7D
  operato
@@ -932,17 +932,26 @@
 perator.
- 
+%0A *%0A * %3Cp%3E
 Conversi
@@ -972,13 +972,48 @@
 ions
-:%0A * 
+ are handled as defined in %0A * %3Ca href=%22
 http
@@ -1078,17 +1078,18 @@
 ons.html
- 
+%22%3E
 Section 
@@ -1093,16 +1093,58 @@
 on 5.6.2
+%0A * of the Java Language Specification%3C/a%3E
 :%0A *%0A * 
@@ -1214,16 +1214,24 @@
 ersion (
+Section 
 5.1.8) i
@@ -1565,18 +1565,8 @@
 %0A *%0A
- * %3Cp%3E%0A *%0A
  * @
@@ -1585,16 +1585,39 @@
 Clement%0A
+ * @author Sam Brannen%0A
  * @sinc
@@ -1670,17 +1670,16 @@
 ator %7B%0A%0A
-%0A
 %09public 
@@ -1783,56 +1783,94 @@
 nts 
-multiply directly here for some types of
+the %7B@code multiply%7D operator directly here for certain types%0A%09 * of supported
  operand
 , ot
@@ -1865,17 +1865,21 @@
  operand
-,
+s and
  otherwi
@@ -1923,96 +1923,117 @@
 ader
- for%0A%09 * types it does not recognize. Supported types here are:%0A%09 * %3Cul%3E%0A%09 * %3Cli%3Einteger
+%0A%09 * for types not supported here.%0A%09 * %0A%09 * %3Cp%3ESupported operand types:%0A%09 * %3Cul%3E%0A%09 * %3Cli%3Edoubles%0A%09 * %3Cli%3Elong
 s%0A%09 
@@ -2030,38 +2030,39 @@
 i%3Elongs%0A%09 * %3Cli%3E
-double
+integer
 s%0A%09 * %3Cli%3Estring
@@ -2671,25 +2671,28 @@
 lue());%0A%09%09%09%7D
- 
+%0A%09%09%09
 else if (lef
@@ -2830,17 +2830,20 @@
 ));%0A%09%09%09%7D
- 
+%0A%09%09%09
 else %7B%0A%09
@@ -2924,17 +2924,19 @@
 %09%09%09%7D%0A%09%09%7D
- 
+%0A%09%09
 else if 

Fix JavaDoc in OpMultiply so that it does not contain special characters