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.Field;
021: import java.lang.reflect.Modifier;
022: import java.util.ArrayList;
023: import java.util.List;
024:
025: import org.jpox.api.ApiAdapter;
026: import org.jpox.exceptions.JPOXUserException;
027: import org.jpox.store.DatastoreClass;
028: import org.jpox.store.mapping.JavaTypeMapping;
029:
030: /**
031: * An expression representing a class.
032: * This is used as follows :-
033: * <UL>
034: * <LI>JDOQL : access public static final fields. Here we invoke accessField on the ClassExpression.</LI>
035: * <LI>JDOQL : use the "instanceof" operator. Here we invoke instanceOf on an ObjectExpression pass in a ClassExpression</LI>
036: * <LI>JPQL : process the FROM candidates so each candidate is a ClassExpression.
037: * Here we set the join(s) for later processing</LI>
038: * </UL>
039: *
040: * @version $Revision: 1.12 $
041: */
042: public class ClassExpression extends ScalarExpression {
043: /** The class being represented. */
044: private Class cls;
045:
046: /** Joins defined for this class. **/
047: private List joinExprs;
048:
049: /**
050: * Constructor.
051: * @param qs The Query Statement
052: * @param cls The class
053: **/
054: public ClassExpression(QueryExpression qs, Class cls) {
055: super (qs);
056:
057: this .cls = cls;
058: }
059:
060: /**
061: * Accessor for the class being represented.
062: * @return The class
063: */
064: public Class getCls() {
065: return cls;
066: }
067:
068: /**
069: * Method called when wanting to call public static final methods on the class.
070: * @param fieldName Name of the public static final field
071: * @param innerJoin Not used
072: * @return Expression for the field access
073: */
074: public ScalarExpression accessField(String fieldName,
075: boolean innerJoin) {
076: try {
077: Field fld = cls.getField(fieldName);
078: if (!Modifier.isStatic(fld.getModifiers())
079: || !Modifier.isFinal(fld.getModifiers())
080: || !Modifier.isPublic(fld.getModifiers())) {
081: throw new JPOXUserException(LOCALISER.msg("037008",
082: fieldName, cls.getName()));
083: }
084: Object value = fld.get(null);
085: if (value == null) {
086: return new NullLiteral(qs);
087: }
088:
089: JavaTypeMapping m = null;
090: ApiAdapter api = qs.getStoreManager().getApiAdapter();
091: if (api.isPersistable(cls)) {
092: // PC class, so maybe has its own table
093: try {
094: // PC class, so maybe has its own table
095: DatastoreClass clsTable = qs.getStoreManager()
096: .getDatastoreClass(cls.getName(),
097: qs.getClassLoaderResolver());
098: m = clsTable.getFieldMapping(fieldName);
099: } catch (Exception e) {
100: // PC class has no table or no such field so just get a default mapping for type
101: m = qs.getStoreManager().getDatastoreAdapter()
102: .getMapping(value.getClass(),
103: qs.getStoreManager(),
104: qs.getClassLoaderResolver());
105: }
106: } else {
107: // Just get a default mapping for type
108: m = qs.getStoreManager().getDatastoreAdapter()
109: .getMapping(value.getClass(),
110: qs.getStoreManager(),
111: qs.getClassLoaderResolver());
112: }
113: return m.newLiteral(qs, value);
114: } catch (IllegalAccessException iae) {
115: // Will not happen since we already checked for it
116: } catch (NoSuchFieldException nsfe) {
117: throw new JPOXUserException(LOCALISER.msg("037009",
118: fieldName, cls.getName()));
119: }
120: return null;
121: }
122:
123: /**
124: * Method to add a join expression for this class.
125: * @param expr Expression to join to
126: * @return This expression
127: */
128: public ScalarExpression join(JoinExpression expr) {
129: if (joinExprs == null) {
130: joinExprs = new ArrayList(); // Joins order has to be preserved
131: }
132: joinExprs.add(expr);
133: return this ;
134: }
135:
136: /**
137: * Accessor for the join expression(s) for this class.
138: * @return Join expressions
139: */
140: public JoinExpression[] getJoins() {
141: if (joinExprs == null) {
142: return null;
143: }
144: return (JoinExpression[]) joinExprs
145: .toArray(new JoinExpression[joinExprs.size()]);
146: }
147: }
|