001: /**********************************************************************
002: Copyright (c) 2005 Andy Jefferson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: ...
018: **********************************************************************/package org.jpox.store.expression;
019:
020: import java.lang.reflect.Constructor;
021: import java.util.ArrayList;
022: import java.util.Arrays;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import org.jpox.exceptions.JPOXUserException;
027: import org.jpox.store.mapping.OIDMapping;
028: import org.jpox.util.ClassUtils;
029:
030: /**
031: * Representation of an expression "new MyObject(param1, param2)" as the result in a JDOQL query.
032: * @version $Revision: 1.7 $
033: */
034: public class NewObjectExpression extends ScalarExpression {
035: /** The class that we need to construct an instance of. */
036: Class newClass = null;
037:
038: /** The arguments to use in the constructor. */
039: List ctrArgs = null;
040:
041: final Constructor ctr;
042:
043: /**
044: * Constructor.
045: * @param qs The query expression
046: * @param cls The class to construct an instance of
047: * @param args the constructor args
048: */
049: public NewObjectExpression(QueryExpression qs, Class cls, List args) {
050: super (qs);
051: this .newClass = cls;
052: ctrArgs = new ArrayList(args);
053:
054: // Check that this constructor exists before going any further
055: Class[] ctrTypes = new Class[args.size()];
056: for (int i = 0; i < args.size(); i++) {
057: if (((ScalarExpression) args.get(i)).getMapping() instanceof OIDMapping) {
058: ctrTypes[i] = qs.getClassLoaderResolver().classForName(
059: ((OIDMapping) ((ScalarExpression) args.get(i))
060: .getMapping()).getType());
061: } else if (args.get(i) instanceof NewObjectExpression) {
062: ctrTypes[i] = ((NewObjectExpression) args.get(i))
063: .getNewClass();
064: } else {
065: ctrTypes[i] = ((ScalarExpression) args.get(i))
066: .getMapping().getJavaType();
067: }
068: }
069: ctr = ClassUtils
070: .getConstructorWithArguments(newClass, ctrTypes);
071: if (ctr == null) {
072: throw new JPOXUserException(LOCALISER.msg("037013",
073: newClass.getName()
074: + typeList(Arrays.asList(ctrTypes))));
075: }
076: }
077:
078: private static String typeList(List exprs) {
079: StringBuffer s = new StringBuffer("(");
080: Iterator i = exprs.iterator();
081:
082: while (i.hasNext()) {
083: s.append(i.next()).append(i.hasNext() ? ',' : ')');
084: }
085:
086: return s.toString();
087: }
088:
089: /**
090: * Accessor for the class of which we should create a new instance.
091: * @return The class
092: */
093: public Class getNewClass() {
094: return newClass;
095: }
096:
097: /**
098: * Accessor for the constructor argument expressions.
099: * @return List of constructor argument expressions
100: */
101: public List getArgumentExpressions() {
102: return ctrArgs;
103: }
104:
105: /**
106: * Method to return the new object using the passed values for the arguments.
107: * @param values The values of the arguments
108: * @return The new object
109: */
110: public Object createNewObject(Object[] values) {
111: if ((values == null || values.length == 0)
112: && ctrArgs.size() > 0) {
113: throw new JPOXUserException(LOCALISER.msg("037014", "0", ""
114: + ctrArgs.size()));
115: }
116: if (values.length != ctrArgs.size()) {
117: throw new JPOXUserException(LOCALISER.msg("037014", ""
118: + values.length, "" + ctrArgs.size()));
119: }
120:
121: Object obj = null;
122: if (ctr != null) {
123: try {
124: obj = ctr.newInstance(values);
125: } catch (Exception e) {
126: throw new JPOXUserException(LOCALISER.msg("037015",
127: newClass.getName(), e));
128: }
129: }
130: return obj;
131: }
132: }
|