/** * INTERNAL Return the descriptor which contains this query key, look in the inheritance hierarchy * of rootDescriptor for the descriptor. */ public ClassDescriptor convertToCastDescriptor( ClassDescriptor rootDescriptor, AbstractSession session) { if (castClass == null || rootDescriptor == null || rootDescriptor.getJavaClass() == castClass) { return rootDescriptor; } ClassDescriptor castDescriptor = session.getClassDescriptor(castClass); if (castDescriptor == null) { throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression()); } if (!castDescriptor.hasInheritance()) { throw QueryException.castMustUseInheritance(getBaseExpression()); } ClassDescriptor parentDescriptor = castDescriptor.getInheritancePolicy().getParentDescriptor(); while (parentDescriptor != null) { if (parentDescriptor == rootDescriptor) { return castDescriptor; } parentDescriptor = parentDescriptor.getInheritancePolicy().getParentDescriptor(); } ClassDescriptor childDescriptor = rootDescriptor; while (childDescriptor != null) { if (childDescriptor == castDescriptor) { return rootDescriptor; } childDescriptor = childDescriptor.getInheritancePolicy().getParentDescriptor(); } throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression()); }
@Override public ClassDescriptor getDescriptor() { if (isAttribute()) { return null; } if (descriptor == null) { // Look first for query keys, then mappings. Ultimately we should have query keys // for everything and can dispense with the mapping part. ForeignReferenceQueryKey queryKey = (ForeignReferenceQueryKey) getQueryKeyOrNull(); if (queryKey != null) { descriptor = convertToCastDescriptor( getSession().getDescriptor(queryKey.getReferenceClass()), getSession()); return descriptor; } if (getMapping() == null) { throw QueryException.invalidQueryKeyInExpression(this); } // We assume this is either a foreign reference or an aggregate mapping descriptor = getMapping().getReferenceDescriptor(); if (getMapping().isVariableOneToOneMapping()) { throw QueryException.cannotQueryAcrossAVariableOneToOneMapping(getMapping(), descriptor); } descriptor = convertToCastDescriptor(descriptor, getSession()); } return descriptor; }
/** * INTERNAL Return true if it uses a cast class and query is downcasting. It will look into * inheritance hierarchy of the root descriptor. */ public boolean isDowncast(ClassDescriptor rootDescriptor, AbstractSession session) { if (castClass == null) { return false; } if (rootDescriptor.getJavaClass() == castClass) { return false; } ClassDescriptor castDescriptor = session.getClassDescriptor(castClass); if (castDescriptor == null) { throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression()); } if (castDescriptor.getInheritancePolicy() == null) { throw QueryException.castMustUseInheritance(getBaseExpression()); } ClassDescriptor parentDescriptor = castDescriptor.getInheritancePolicy().getParentDescriptor(); while (parentDescriptor != null) { if (parentDescriptor == rootDescriptor) { return true; } parentDescriptor = parentDescriptor.getInheritancePolicy().getParentDescriptor(); } throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression()); }
/** * Processes the HTTP request. Parses new modules and discards obsolete ones. * * @param http HTTP context * @throws Exception exception */ void process(final HTTPContext http) throws Exception { try { module.process(http, this); } catch (final QueryException ex) { if (ex.file() == null) ex.info(function.info); throw ex; } }
/** INTERNAL: Ensure that the descriptor has been set. */ public void checkDescriptor(Object object, AbstractSession session) throws QueryException { if (this.descriptor == null) { if (object == null) { throw QueryException.objectToModifyNotSpecified(this); } // Bug#3947714 Pass the object instead of class in case object is proxy ClassDescriptor referenceDescriptor = session.getDescriptor(object); if (referenceDescriptor == null) { throw QueryException.descriptorIsMissing(object.getClass(), this); } setDescriptor(referenceDescriptor); } }
public DatabaseMapping getMappingFromQueryKey() { QueryKey queryKey = getQueryKeyOrNull(); if ((queryKey == null) || (!(queryKey instanceof DirectQueryKey))) { throw QueryException.cannotConformExpression(); } mapping = queryKey .getDescriptor() .getObjectBuilder() .getMappingForField(((DirectQueryKey) queryKey).getField()); if (mapping == null) { throw QueryException.cannotConformExpression(); } return mapping; }
/** INTERNAL: Return if the expression is for a direct mapped attribute. */ public boolean isAttribute() { if (isAttributeExpression == null) { if (getSession() == null) { // We can't tell, so say no. return false; } QueryKey queryKey = getQueryKeyOrNull(); if (queryKey != null) { isAttributeExpression = Boolean.valueOf(queryKey.isDirectQueryKey()); } else { DatabaseMapping mapping = getMapping(); if (mapping != null) { if (mapping.isVariableOneToOneMapping()) { throw QueryException.cannotQueryAcrossAVariableOneToOneMapping( mapping, mapping.getDescriptor()); } else { isAttributeExpression = Boolean.valueOf(mapping.isDirectToFieldMapping()); } } else { isAttributeExpression = Boolean.FALSE; } } } return isAttributeExpression.booleanValue(); }
/** * INTERNAL: Add element into the container. * * @param element java.lang.Object * @param container java.lang.Object * @return boolean indicating whether the container changed */ protected boolean addInto(Object key, Object element, Object container) { try { ((IndirectList) container).addElement(element); return true; } catch (ClassCastException ex) { throw QueryException.cannotAddElement(element, container, ex); } }
/** * PUBLIC: Configure the query to use an instance of the specified container class to hold the * result objects. The key used to index the value in the Map is the value returned by a call to * the specified zero-argument method. The method must be implemented by the class (or a * superclass) of the value to be inserted into the Map. * * <p>jdk1.2.x: The container class must implement (directly or indirectly) the Map interface. * * <p>jdk1.1.x: The container class must be a subclass of Hashtable. * * <p>The referenceClass must set before calling this method. */ public void useMapClass(Class concreteClass, String methodName) { // the reference class has to be specified before coming here if (getReferenceClass() == null) { throw QueryException.referenceClassMissing(this); } ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteClass); policy.setKeyName(methodName, getReferenceClass().getName()); setContainerPolicy(policy); }
/** * INTERNAL: Return the lowlevel database accessor. The database accessor is used for direct * database access. The right accessor for this broker will be returned. */ public Accessor getAccessor(Class domainClass) { if (domainClass == null) { // CR#... this occurs if a data query is used without a session-name, needs to throw an error throw QueryException.unnamedQueryOnSessionBroker(null); } // session may be a broker too. Eventually a non session broker wil be found return getSessionForClass(domainClass).getAccessor(domainClass); }
/** Do any required validation for this node. Throw an exception if it's incorrect. */ public void validateNode() { if ((getQueryKeyOrNull() == null) && (getMapping() == null)) { throw QueryException.invalidQueryKeyInExpression(getName()); } QueryKey queryKey = getQueryKeyOrNull(); DatabaseMapping mapping = getMapping(); Object theOneThatsNotNull = null; boolean qkIsToMany = false; if (queryKey != null) { theOneThatsNotNull = queryKey; qkIsToMany = queryKey.isManyToManyQueryKey() || queryKey.isOneToManyQueryKey(); } boolean isNestedMapping = false; if (mapping != null) { // Bug 2847621 - Add Aggregate Collection to the list of valid items for outer join. if (shouldUseOuterJoin && (!(mapping.isOneToOneMapping() || mapping.isOneToManyMapping() || mapping.isManyToManyMapping() || mapping.isAggregateCollectionMapping() || mapping.isDirectCollectionMapping()))) { throw QueryException.outerJoinIsOnlyValidForOneToOneMappings(getMapping()); } qkIsToMany = mapping.isCollectionMapping(); if (index != null) { if (qkIsToMany) { CollectionMapping collectionMapping = (CollectionMapping) getMapping(); if (collectionMapping.getListOrderField() != null) { index.setField(collectionMapping.getListOrderField()); if (collectionMapping.shouldUseListOrderFieldTableExpression()) { Expression newBase = getTable(collectionMapping.getListOrderField().getTable()); index.setBaseExpression(newBase); } else { addDerivedField(index); } } else { throw QueryException.indexRequiresCollectionMappingWithListOrderField( this, collectionMapping); } } else { throw QueryException.indexRequiresCollectionMappingWithListOrderField(this, mapping); } } isNestedMapping = mapping.isNestedTableMapping(); theOneThatsNotNull = mapping; } else { if (index != null) { throw QueryException.indexRequiresCollectionMappingWithListOrderField(this, null); } } if ((!shouldQueryToManyRelationship()) && qkIsToMany && (!isNestedMapping)) { throw QueryException.invalidUseOfToManyQueryKeyInExpression(theOneThatsNotNull); } if (shouldQueryToManyRelationship() && !qkIsToMany) { throw QueryException.invalidUseOfAnyOfInExpression(theOneThatsNotNull); } }
protected void execute(String queryString, HttpAction action) { String queryStringLog = ServletOps.formatForLog(queryString); if (action.verbose) action.log.info(format("[%d] Query = \n%s", action.id, queryString)); else action.log.info(format("[%d] Query = %s", action.id, queryStringLog)); Query query = null; try { // NB syntax is ARQ (a superset of SPARQL) query = QueryFactory.create(queryString, QueryParseBase, Syntax.syntaxARQ); queryStringLog = formatForLog(query); validateQuery(action, query); } catch (ActionErrorException ex) { throw ex; } catch (QueryParseException ex) { ServletOps.errorBadRequest( "Parse error: \n" + queryString + "\n\r" + messageForQueryException(ex)); } // Should not happen. catch (QueryException ex) { ServletOps.errorBadRequest("Error: \n" + queryString + "\n\r" + ex.getMessage()); } // Assumes finished whole thing by end of sendResult. try { action.beginRead(); Dataset dataset = decideDataset(action, query, queryStringLog); try (QueryExecution qExec = createQueryExecution(query, dataset); ) { SPARQLResult result = executeQuery(action, qExec, query, queryStringLog); // Deals with exceptions itself. sendResults(action, result, query.getPrologue()); } } catch (QueryParseException ex) { // Late stage static error (e.g. bad fixed Lucene query string). ServletOps.errorBadRequest( "Query parse error: \n" + queryString + "\n\r" + messageForQueryException(ex)); } catch (QueryCancelledException ex) { // Additional counter information. incCounter(action.getEndpoint().getCounters(), QueryTimeouts); throw ex; } finally { action.endRead(); } }
/** * INTERNAL: Remove elements from this container starting with this index * * @param beginIndex int the point to start deleting values from the collection * @param container java.lang.Object * @return boolean indicating whether the container changed */ public void removeFromWithOrder(int beginIndex, Object container) { int size = sizeFor(container) - 1; try { for (; size >= beginIndex; --size) { ((IndirectList) container).removeElementAt(size); } } catch (ClassCastException ex1) { throw QueryException.cannotRemoveFromContainer(new Integer(size), container, this); } }
/** * Refreshes the view after a file has been saved. * * @param root root directory * @param ctx database context * @throws InterruptedException interruption */ void parse(final IOFile root, final Context ctx) throws InterruptedException { final long id = ++parseId; final HashSet<String> parsed = new HashSet<>(); final TreeMap<String, InputInfo> errs = new TreeMap<>(); // collect files to be parsed final ProjectCache pc = cache(root); final StringList mods = new StringList(), lmods = new StringList(); for (final String path : pc) { final IOFile file = new IOFile(path); if (file.hasSuffix(IO.XQSUFFIXES)) (file.hasSuffix(IO.XQMSUFFIX) ? lmods : mods).add(path); } mods.add(lmods); // parse modules for (final String path : mods) { if (id != parseId) throw new InterruptedException(); if (parsed.contains(path)) continue; final IOFile file = new IOFile(path); try (final TextInput ti = new TextInput(file)) { // parse query try (final QueryContext qc = new QueryContext(ctx)) { final String input = ti.cache().toString(); final boolean lib = QueryProcessor.isLibrary(input); qc.parse(input, lib, path, null); // parsing was successful: remember path parsed.add(path); for (final byte[] mod : qc.modParsed) parsed.add(Token.string(mod)); } catch (final QueryException ex) { // parsing failed: remember path final InputInfo ii = ex.info(); errs.put(path, ii); parsed.add(ii.path()); } } catch (final IOException ex) { // file may not be accessible Util.debug(ex); } } errors = errs; }
/** * INTERNAL: Execute the query. If there are cached results return those. This must override the * super to support result caching. * * @param session - the session in which the receiver will be executed. * @return An object or vector, the result of executing the query. * @exception DatabaseException - an error has occurred on the database */ public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException { if (shouldCacheQueryResults()) { if (getContainerPolicy().overridesRead()) { throw QueryException.cannotCacheCursorResultsOnQuery(this); } if (shouldConformResultsInUnitOfWork()) { throw QueryException.cannotConformAndCacheQueryResults(this); } if (isPrepared()) { // only prepared queries can have cached results. Object queryResults = getQueryResults(session, row, true); if (queryResults != null) { if (QueryMonitor.shouldMonitor()) { QueryMonitor.incrementReadAllHits(this); } // bug6138532 - check for "cached no results" (InvalidObject singleton) in query // results, and return an empty container instance as configured if (queryResults == InvalidObject.instance) { return getContainerPolicy().containerInstance(0); } Collection results = (Collection) queryResults; if (session.isUnitOfWork()) { ContainerPolicy policy = getContainerPolicy(); Object resultCollection = policy.containerInstance(results.size()); Object iterator = policy.iteratorFor(results); while (policy.hasNext(iterator)) { Object result = ((UnitOfWorkImpl) session) .registerExistingObject(policy.next(iterator, session), this.descriptor); policy.addInto(result, resultCollection, session); } return resultCollection; } return results; } } } if (QueryMonitor.shouldMonitor()) { QueryMonitor.incrementReadAllMisses(this); } return super.execute(session, row); }
@Override protected void runTestForReal() throws Throwable { Query query = null; try { try { query = queryFromTestItem(testItem); } catch (QueryException qEx) { query = null; qEx.printStackTrace(System.err); fail("Parse failure: " + qEx.getMessage()); throw qEx; } Dataset dataset = setUpDataset(query, testItem); if (dataset == null && !doesQueryHaveDataset(query)) fail("No dataset for query"); QueryExecution qe = null; if (dataset == null) qe = QueryExecutionFactory.create(query, queryFileManager); else qe = QueryExecutionFactory.create(query, dataset); try { if (query.isSelectType()) runTestSelect(query, qe); else if (query.isConstructType()) runTestConstruct(query, qe); else if (query.isDescribeType()) runTestDescribe(query, qe); else if (query.isAskType()) runTestAsk(query, qe); } finally { qe.close(); } } catch (IOException ioEx) { // log.debug("IOException: ",ioEx) ; fail("IOException: " + ioEx.getMessage()); throw ioEx; } catch (NullPointerException ex) { throw ex; } catch (Exception ex) { ex.printStackTrace(System.err); fail("Exception: " + ex.getClass().getName() + ": " + ex.getMessage()); } }
/** Append the string containing the SQL insert string for the given table. */ protected SQLCall buildCallWithoutReturning(AbstractSession session) { SQLCall call = new SQLCall(); call.returnNothing(); Writer writer = new CharArrayWriter(200); try { writer.write("INSERT "); if (getHintString() != null) { writer.write(getHintString()); writer.write(" "); } writer.write("INTO "); writer.write(getTable().getQualifiedNameDelimited(session.getPlatform())); writer.write(" ("); Vector fieldsForTable = new Vector(); for (Enumeration fieldsEnum = getModifyRow().keys(); fieldsEnum.hasMoreElements(); ) { DatabaseField field = (DatabaseField) fieldsEnum.nextElement(); if (field.getTable().equals(getTable()) || (!field.hasTableName())) { fieldsForTable.addElement(field); } } if (fieldsForTable.isEmpty()) { throw QueryException.objectToInsertIsEmpty(getTable()); } for (int i = 0; i < fieldsForTable.size(); i++) { writer.write( ((DatabaseField) fieldsForTable.elementAt(i)).getNameDelimited(session.getPlatform())); if ((i + 1) < fieldsForTable.size()) { writer.write(", "); } } writer.write(") VALUES ("); for (int i = 0; i < fieldsForTable.size(); i++) { DatabaseField field = (DatabaseField) fieldsForTable.elementAt(i); call.appendModify(writer, field); if ((i + 1) < fieldsForTable.size()) { writer.write(", "); } } writer.write(")"); call.setSQLString(writer.toString()); } catch (IOException exception) { throw ValidationException.fileError(exception); } return call; }
/** INTERNAL: Answers the session to be used for the given query. */ protected AbstractSession getSessionForQuery(DatabaseQuery query) { if (query.hasSessionName()) { return getSessionForName(query.getSessionName()); } Class queryClass; if (query.getDescriptor() != null) { queryClass = query.getDescriptor().getJavaClass(); } else { queryClass = query.getReferenceClass(); if (queryClass == null) { throw QueryException.unnamedQueryOnSessionBroker(query); } } return getSessionForClass(queryClass); }
/** * INTERNAL: Add element into a container which implements the Collection interface. * * @param element java.lang.Object * @param container java.lang.Object * @return boolean indicating whether the container changed */ public void addIntoWithOrder(Vector indexes, Hashtable elements, Object container) { Object object = null; try { Enumeration indexEnum = indexes.elements(); while (indexEnum.hasMoreElements()) { Integer index = (Integer) indexEnum.nextElement(); object = elements.get(index); if (index.intValue() >= (sizeFor(container) - 1)) { ((IndirectList) container).addElement(object); } else { ((IndirectList) container).setElementAt(object, index.intValue()); } } } catch (ClassCastException ex1) { throw QueryException.cannotAddElement(object, container, ex1); } }
/** * INTERNAL: Execute the query. If there are cached results return those. This must override the * super to support result caching. * * @param aSession - the session in which the receiver will be executed. * @return An object or vector, the result of executing the query. * @exception DatabaseException - an error has occurred on the database */ public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException { if (shouldCacheQueryResults()) { if (getContainerPolicy().overridesRead()) { throw QueryException.cannotCacheCursorResultsOnQuery(this); } if (isPrepared()) { // only prepared queries can have cached results. Object results = getQueryResults(session, row, true); // Bug6138532 - if results are "cached no results", return null immediately if (results == InvalidObject.instance) { return null; } if (results != null) { return results; } } } return super.execute(session, row); }
public QueryKey getQueryKeyOrNull() { if (!hasQueryKey) { return null; } // Oct 19, 2000 JED // Added try/catch. This was throwing a NPE in the following case // expresssionBuilder.get("firstName").get("bob") // moved by Gordon Yorke to cover validate and normalize if (getContainingDescriptor() == null) { throw QueryException.invalidQueryKeyInExpression(getName()); } if (queryKey == null) { queryKey = getContainingDescriptor().getQueryKeyNamed(getName()); if (queryKey == null) { hasQueryKey = false; } } return queryKey; }
/** INTERNAL: Prepare the receiver for execution in a session. */ public void prepareForExecution() throws QueryException { super.prepareForExecution(); if (getObject() == null) { throw QueryException.objectToModifyNotSpecified(this); } setObject(this.descriptor.getObjectBuilder().unwrapObject(getObject(), getSession())); if (this.descriptor == null) { setDescriptor(getSession().getDescriptor(getObject().getClass())); } if (getPrimaryKey() == null) { setPrimaryKey( this.descriptor .getObjectBuilder() .extractPrimaryKeyFromObject(getObject(), getSession())); } if ((getTranslationRow() == null) || (getTranslationRow().isEmpty())) { setTranslationRow( this.descriptor.getObjectBuilder().buildRowForTranslation(getObject(), getSession())); } }
/** * PUBLIC: Specify the foreign-reference mapped attribute to be optimized in this query. The query * will execute normally, however when any of the batched parts is accessed, the parts will all be * read in a single query, this allows all of the data required for the parts to be read in a * single query instead of (n) queries. This should be used when the application knows that it * requires the part for all of the objects being read. This can be used for one-to-one, * one-to-many, many-to-many and direct collection mappings. * * <p>The use of the expression allows for nested batch reading to be expressed. * * <p>Example: query.addBatchReadAttribute("phoneNumbers") * * @see #addBatchReadAttribute(Expression) * @see ObjectLevelReadQuery#addJoinedAttribute(String) */ public void addBatchReadAttribute(String attributeName) { if (!getQueryMechanism().isExpressionQueryMechanism()) { throw QueryException.batchReadingNotSupported(this); } getBatchReadAttributeExpressions().add(getExpressionBuilder().get(attributeName)); }
/** * INTERNAL: Possible for future development, not currently supported. * * <p>Retrieve the value through using batch reading. This executes a single query to read the * target for all of the objects and stores the result of the batch query in the original query to * allow the other objects to share the results. */ @Override protected Object batchedValueFromRow(AbstractRecord row, ReadAllQuery query) { throw QueryException.batchReadingNotSupported(this, query); }
/** * Tests if errors are thrown when some mandatory attributes are missing in a <http:request/>, * <http:body/> or <http:multipart/>. * * @throws IOException I/O Exception */ @Test public void errors() throws IOException { // Incorrect requests final List<byte[]> falseReqs = new ArrayList<>(); // Request without method final byte[] falseReq1 = token( "<http:request " + "xmlns:http='http://expath.org/ns/http-client' " + "href='" + REST_ROOT + "'/>"); falseReqs.add(falseReq1); // Request with send-authorization and no credentials final byte[] falseReq2 = token( "<http:request " + "xmlns:http='http://expath.org/ns/http-client' " + "method='GET' href='" + REST_ROOT + "' " + "send-authorization='true'/>"); falseReqs.add(falseReq2); // Request with send-authorization and only username final byte[] falseReq3 = token( "<http:request " + "xmlns:http='http://expath.org/ns/http-client' " + "method='GET' href='" + REST_ROOT + "' " + "send-authorization='true' username='******'/>"); falseReqs.add(falseReq3); // Request with body that has no media-type final byte[] falseReq4 = token( "<http:request " + "xmlns:http='http://expath.org/ns/http-client' " + "method='POST' href='" + REST_ROOT + "'>" + "<http:body>" + "</http:body>" + "</http:request>"); falseReqs.add(falseReq4); // Request with multipart that has no media-type final byte[] falseReq5 = token( "<http:request method='POST' " + "xmlns:http='http://expath.org/ns/http-client' " + "href='" + REST_ROOT + "'>" + "<http:multipart boundary='xxx'>" + "</http:multipart>" + "</http:request>"); falseReqs.add(falseReq5); // Request with multipart with part that has a body without media-type final byte[] falseReq6 = token( "<http:request method='POST' " + "xmlns:http='http://expath.org/ns/http-client' " + "href='" + REST_ROOT + "'>" + "<http:multipart boundary='xxx'>" + "<http:header name='hdr1' value-='val1'/>" + "<http:body media-type='text/plain'>" + "Part1" + "</http:body>" + "<http:header name='hdr1' value-='val1'/>" + "<http:body>" + "Part1" + "</http:body>" + "</http:multipart>" + "</http:request>"); falseReqs.add(falseReq6); // Request with schema different from http final byte[] falseReq7 = token( "<http:request " + "xmlns:http='http://expath.org/ns/http-client' " + "href='ftp://basex.org'/>"); falseReqs.add(falseReq7); // Request with content and method which must be empty final byte[] falseReq8 = token( "<http:request " + "xmlns:http='http://expath.org/ns/http-client' " + "method='DELETE' href='" + REST_ROOT + "'>" + "<http:body media-type='text/plain'>" + "</http:body>" + "</http:request>"); falseReqs.add(falseReq8); for (final byte[] falseReq : falseReqs) { final DBNode dbNode = new DBNode(new IOContent(falseReq)); try { final HttpRequestParser rp = new HttpRequestParser(null); rp.parse(dbNode.children().next(), null); fail("Exception not thrown"); } catch (final QueryException ex) { assertTrue(ex.getMessage().contains(ErrType.HC.toString())); } } }
/** * INTERNAL This method iterates through a collection and gets the values from the objects to * conform in an in-memory query. Creation date: (1/19/01 1:18:27 PM) */ public Object valuesFromCollection( Object object, AbstractSession session, int valueHolderPolicy, boolean isObjectUnregistered) { // in case the mapping is null - this can happen if a query key is being used // In this case, check for the query key and find it's mapping. boolean readMappingFromQueryKey = false; if (getMapping() == null) { getMappingFromQueryKey(); readMappingFromQueryKey = true; } // For bug 2780817 get the mapping directly from the object. In EJB 2.0 // inheritance, each child must override mappings defined in an abstract // class with its own. DatabaseMapping mapping = this.mapping; ClassDescriptor descriptor = mapping.getDescriptor(); if (descriptor.hasInheritance() && (descriptor.getJavaClass() != object.getClass())) { mapping = session .getDescriptor(object.getClass()) .getObjectBuilder() .getMappingForAttributeName(getName()); descriptor = mapping.getDescriptor(); } // fetch group support if (descriptor.hasFetchGroupManager()) { FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager(); if (fetchGroupManager.isPartialObject(object) && (!fetchGroupManager.isAttributeFetched(object, mapping.getAttributeName()))) { // the conforming attribute is not fetched, simply throw exception throw QueryException.cannotConformUnfetchedAttribute(mapping.getAttributeName()); } } if (mapping.isDirectToFieldMapping()) { return ((AbstractDirectMapping) mapping).valueFromObject(object, mapping.getField(), session); } else if (mapping.isForeignReferenceMapping()) { // CR 3677 integration of a ValueHolderPolicy Object valueFromMapping = mapping.getAttributeValueFromObject(object); if (!((ForeignReferenceMapping) mapping) .getIndirectionPolicy() .objectIsInstantiated(valueFromMapping)) { if (valueHolderPolicy != InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION) { // If the client wishes us to trigger the indirection then we should do so, // Other wise throw the exception throw QueryException .mustInstantiateValueholders(); // you should instantiate the valueholder for this to // work } // maybe we should throw this exception from the start, to save time } Object valueToIterate = mapping.getRealAttributeValueFromObject(object, session); UnitOfWorkImpl uow = isObjectUnregistered ? (UnitOfWorkImpl) session : null; // First check that object in fact is unregistered. // toDo: ?? Why is this commented out? Why are we supporting the unregistered thing at all? // Does not seem to be any public API for this, nor every used internally? // if (isObjectUnregistered) { // isObjectUnregistered = !uow.getCloneMapping().containsKey(object); // } if (mapping.isCollectionMapping() && (valueToIterate != null)) { // For bug 2766379 must use the correct version of vectorFor to // unwrap the result same time. valueToIterate = mapping.getContainerPolicy().vectorFor(valueToIterate, session); // toDo: If the value is empty, need to support correct inner/outer join filtering // symantics. // For CR 2612601, try to partially replace the result with already // registered objects. if (isObjectUnregistered && (uow.getCloneMapping().get(object) == null)) { Vector objectValues = (Vector) valueToIterate; for (int i = 0; i < objectValues.size(); i++) { Object original = objectValues.elementAt(i); Object clone = uow.getIdentityMapAccessorInstance() .getIdentityMapManager() .getFromIdentityMap(original); if (clone != null) { objectValues.setElementAt(clone, i); } } } // For CR 2612601, conforming without registering, a query could be // bob.get("address").get("city").equal("Ottawa"); where the address // has been registered and modified in the UOW, but bob has not. Thus // even though bob does not point to the modified address now, it will // as soon as it is registered, so should point to it here. } else if (isObjectUnregistered && (uow.getCloneMapping().get(object) == null)) { Object clone = uow.getIdentityMapAccessorInstance() .getIdentityMapManager() .getFromIdentityMap(valueToIterate); if (clone != null) { valueToIterate = clone; } } return valueToIterate; } else if (mapping.isAggregateMapping()) { Object aggregateValue = mapping.getAttributeValueFromObject(object); // Bug 3995468 - if this query key is to a mapping in an aggregate object, get the object from // actual mapping rather than the aggregate mapping while (readMappingFromQueryKey && mapping.isAggregateObjectMapping() && !((AggregateObjectMapping) mapping) .getReferenceClass() .equals(queryKey.getDescriptor().getJavaClass())) { mapping = mapping .getReferenceDescriptor() .getObjectBuilder() .getMappingForField(((DirectQueryKey) queryKey).getField()); aggregateValue = mapping.getRealAttributeValueFromObject(aggregateValue, session); } return aggregateValue; } else { throw QueryException.cannotConformExpression(); } }