001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.policy.jaxws.xmlstreamwriter;
038:
039: import java.lang.reflect.InvocationTargetException;
040: import java.lang.reflect.Method;
041: import java.util.ArrayList;
042: import java.util.Arrays;
043: import java.util.List;
044: import javax.xml.stream.XMLStreamWriter;
045:
046: import com.sun.xml.ws.policy.privateutil.PolicyLogger;
047:
048: import static com.sun.xml.ws.policy.jaxws.xmlstreamwriter.XmlStreamWriterMethodType.WRITE_CHARACTERS;
049: import static com.sun.xml.ws.policy.jaxws.privateutil.LocalizationMessages.WSP_1052_NO_ARGUMENTS_IN_INVOCATION;
050:
051: /**
052: * The class represents a wrapper around {@code XMLStreamWriter} invocations.
053: *
054: * @author Marek Potociar (marek.potociar at sun.com)
055: */
056: public final class Invocation {
057: private static final PolicyLogger LOGGER = PolicyLogger
058: .getLogger(Invocation.class);
059:
060: private final Method method;
061: private final Object[] arguments;
062: private String argsString;
063: private final XmlStreamWriterMethodType methodType;
064:
065: /**
066: * Factory method that creates {@link Invocation} instance according to input
067: * arguments
068: *
069: * @param method method represented by the {@link Invocation} instance returned
070: * as a result of this factory method call
071: * @param args invocation arguments to be passed to the method when {@link #execute()}
072: * method is invoked on the {@link Invocation} instance.
073: * @return the {@link Invocation} instance representing invocation of method
074: * defined by value of {@code method} argument.
075: */
076: public static Invocation createInvocation(final Method method,
077: final Object[] args) {
078: final Object[] arguments;
079: final XmlStreamWriterMethodType methodType = XmlStreamWriterMethodType
080: .getMethodType(method.getName());
081: if (methodType == WRITE_CHARACTERS && args.length == 3) {
082: final Integer start = (Integer) args[1];
083: final Integer length = (Integer) args[2];
084: final char[] charArrayCopy = new char[length.intValue()];
085: System.arraycopy(args[0], start, charArrayCopy, 0, length);
086:
087: arguments = new Object[3];
088: arguments[0] = charArrayCopy;
089: arguments[1] = Integer.valueOf(0);
090: arguments[2] = length;
091: } else {
092: arguments = args;
093: }
094:
095: return new Invocation(method, methodType, arguments);
096: }
097:
098: /**
099: * Private constructor of the class used in the {@link createInvocation(Method, Object[])}
100: * factory method.
101: *
102: * @param method method represented by the new {@link Invocation} instance
103: * @param type method type represented by the new {@link Invocation} instance
104: * @param args invocation arguments to be passed to the method when {@link #execute()}
105: * method is invoked on the {@link Invocation} instance.
106: *
107: * @see XmlStreamWriterMethodType
108: */
109: private Invocation(final Method method,
110: final XmlStreamWriterMethodType type, final Object[] args) {
111: this .method = method;
112: this .arguments = args;
113: this .methodType = type;
114: }
115:
116: /**
117: * Returns information about the name of the method represented by this {@link Invocation} instance
118: *
119: * @return method name represented by this {@link Invocation} instance
120: */
121: public String getMethodName() {
122: return method.getName();
123: }
124:
125: /**
126: * Returns information about the type of the method represented by this {@link Invocation} instance
127: *
128: * @return method type represented by this {@link Invocation} instance
129: * @see XmlStreamWriterMethodType
130: */
131: public XmlStreamWriterMethodType getMethodType() {
132: return methodType;
133: }
134:
135: /**
136: * Returns single invocation argument for this {@link Invocation} instance that
137: * is stored in the invocation arguments array at position determined by {@code index}
138: * argument.
139: *
140: * @return single invocation argument for this {@link Invocation} instance at
141: * position determined by {@code index} argument
142: *
143: * @throws ArrayIndexOutOfBoundsException if there are no arguments in the array
144: * or if the index parameter is out of bounds of invocation arguments array
145: */
146: public Object getArgument(final int index)
147: throws ArrayIndexOutOfBoundsException {
148: if (arguments == null) {
149: throw LOGGER
150: .logSevereException(new ArrayIndexOutOfBoundsException(
151: WSP_1052_NO_ARGUMENTS_IN_INVOCATION(this
152: .toString())));
153: }
154: return arguments[index];
155: }
156:
157: /**
158: * Returns information about the number of arguments stored in this {@link Invocation}
159: * instance
160: *
161: * @return number of arguments stored in this {@link Invocation} instance
162: */
163: public int getArgumentsCount() {
164: return (arguments == null) ? 0 : arguments.length;
165: }
166:
167: /**
168: * Executes the method on {@code target} {@code XMLStreamWriter} instance.
169: *
170: * @return execution result.
171: * @exception IllegalAccessException see {@link java.lang.reflect.Method.invoke(Object, Object[]) Method.invoke()}.
172: * @exception IllegalArgumentException see {@link java.lang.reflect.Method.invoke(Object, Object[]) Method.invoke()}.
173: * @exception InvocationTargetException see {@link java.lang.reflect.Method.invoke(Object, Object[]) Method.invoke()}.
174: * @exception NullPointerException see {@link java.lang.reflect.Method.invoke(Object, Object[]) Method.invoke()}.
175: * @exception ExceptionInInitializerError see {@link java.lang.reflect.Method.invoke(Object, Object[]) Method.invoke()}.
176: */
177: public Object execute(final XMLStreamWriter target)
178: throws IllegalAccessException, InvocationTargetException,
179: IllegalArgumentException {
180: return method.invoke(target, arguments);
181: }
182:
183: /**
184: * Method returns {@link String} representation of the {@link Invocation} instance.
185: *
186: * @return {@link String} representation of the {@link Invocation} instance.
187: */
188: public String toString() {
189: final StringBuffer retValue = new StringBuffer(30);
190: retValue.append("invocation { method='").append(
191: method.getName()).append("', args=").append(
192: argsToString());
193: retValue.append('}');
194:
195: return retValue.toString();
196: }
197:
198: /**
199: * Method returns {@link String} representation of arguments stored in the
200: * {@link Invocation} instance.
201: *
202: * @return {@link String} representation of arguments stored in the {@link Invocation}
203: * instance.
204: */
205: public String argsToString() {
206: if (argsString == null) {
207: List<Object> argList = null;
208: if (arguments != null && arguments.length > 0) {
209: if (arguments.length == 3
210: && "writeCharacters".equals(method.getName())) {
211: argList = new ArrayList<Object>(3);
212: argList.add(new String((char[]) arguments[0]));
213: argList.add(arguments[1]);
214: argList.add(arguments[2]);
215: } else {
216: argList = Arrays.asList(arguments);
217: }
218: }
219: argsString = (argList == null) ? "no arguments" : argList
220: .toString();
221: }
222:
223: return argsString;
224: }
225: }
|