KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > access > DataContextQueryAction


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.access;
21
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import org.apache.cayenne.ObjectContext;
27 import org.apache.cayenne.PersistenceState;
28 import org.apache.cayenne.Persistent;
29 import org.apache.cayenne.QueryResponse;
30 import org.apache.cayenne.cache.QueryCache;
31 import org.apache.cayenne.query.ObjectIdQuery;
32 import org.apache.cayenne.query.Query;
33 import org.apache.cayenne.query.RefreshQuery;
34 import org.apache.cayenne.util.ListResponse;
35 import org.apache.cayenne.util.ObjectContextQueryAction;
36
37 /**
38  * A DataContext-specific version of
39  * {@link org.apache.cayenne.util.ObjectContextQueryAction}.
40  *
41  * @since 1.2
42  * @author Andrus Adamchik
43  */

44 // TODO: Andrus, 2/2/2006 - all these DataContext extensions should become available to
45
// CayenneContext as well....
46
class DataContextQueryAction extends ObjectContextQueryAction {
47
48     public DataContextQueryAction(DataContext actingContext, ObjectContext targetContext,
49             Query query) {
50         super(actingContext, targetContext, query);
51     }
52
53     public QueryResponse execute() {
54         if (interceptPaginatedQuery() != DONE) {
55             if (interceptOIDQuery() != DONE) {
56                 if (interceptRelationshipQuery() != DONE) {
57                     if (interceptRefreshQuery() != DONE) {
58                         if (interceptLocalCache() != DONE) {
59                             runQuery();
60                         }
61                     }
62                 }
63             }
64         }
65
66         interceptObjectConversion();
67         return response;
68     }
69
70     /**
71      * Overrides super implementation to property handle data row fetches.
72      */

73     protected boolean interceptOIDQuery() {
74         if (query instanceof ObjectIdQuery) {
75             ObjectIdQuery oidQuery = (ObjectIdQuery) query;
76
77             if (!oidQuery.isFetchMandatory()) {
78                 Object JavaDoc object = actingContext.getGraphManager().getNode(
79                         oidQuery.getObjectId());
80                 if (object != null) {
81
82                     // TODO: andrus, 10/14/2006 - obtaining a row from an object is the
83
// only piece that makes this method different from the super
84
// implementation. This is used in NEW objects sorting on insert. It
85
// would be nice to implement an alternative algorithm that wouldn't
86
// require this hack.
87
if (oidQuery.isFetchingDataRows()) {
88                         object = ((DataContext) actingContext)
89                                 .currentSnapshot((Persistent) object);
90                     }
91                     // do not return hollow objects
92
else if (((Persistent) object).getPersistenceState() == PersistenceState.HOLLOW) {
93                         return !DONE;
94                     }
95
96                     this.response = new ListResponse(object);
97                     return DONE;
98                 }
99             }
100         }
101
102         return !DONE;
103     }
104
105     private boolean interceptPaginatedQuery() {
106         if (metadata.getPageSize() > 0) {
107             response = new ListResponse(new IncrementalFaultList(
108                     (DataContext) actingContext,
109                     query));
110             return DONE;
111         }
112
113         return !DONE;
114     }
115
116     protected QueryCache getQueryCache() {
117         return ((DataContext) actingContext).getQueryCache();
118     }
119
120     private boolean interceptRefreshQuery() {
121         if (query instanceof RefreshQuery) {
122             RefreshQuery refreshQuery = (RefreshQuery) query;
123
124             DataContext context = (DataContext) actingContext;
125
126             // handle four separate cases, but do not combine them as it will be
127
// unclear how to handle cascading behavior
128

129             // 1. refresh all
130
if (refreshQuery.isRefreshAll()) {
131                 synchronized (context.getObjectStore()) {
132
133                     invalidateLocally(context.getObjectStore(), context
134                             .getObjectStore()
135                             .getObjectIterator());
136
137                     context.getQueryCache().clear();
138                 }
139
140                 // cascade
141
return !DONE;
142             }
143
144             // 2. invalidate object collection
145
Collection JavaDoc objects = refreshQuery.getObjects();
146             if (objects != null && !objects.isEmpty()) {
147
148                 synchronized (context.getObjectStore()) {
149                     invalidateLocally(context.getObjectStore(), objects.iterator());
150                 }
151
152                 // cascade
153
return !DONE;
154             }
155
156             // 3. refresh query - have to do it eagerly to refresh the objects involved
157
Query cachedQuery = refreshQuery.getQuery();
158             if (cachedQuery != null) {
159
160                 String JavaDoc cacheKey = cachedQuery
161                         .getMetaData(context.getEntityResolver())
162                         .getCacheKey();
163                 context.getQueryCache().remove(cacheKey);
164
165                 this.response = context.performGenericQuery(cachedQuery);
166
167                 // do not cascade to avoid running query twice
168
return DONE;
169             }
170
171             // 4. refresh groups...
172
String JavaDoc[] groups = refreshQuery.getGroupKeys();
173             if (groups != null && groups.length > 0) {
174
175                 for (int i = 0; i < groups.length; i++) {
176                     context.getQueryCache().removeGroup(groups[i]);
177                 }
178
179                 // cascade group invalidation
180
return !DONE;
181             }
182
183             // shouldn't ever happen
184
return DONE;
185         }
186
187         return !DONE;
188     }
189
190     private void invalidateLocally(ObjectStore objectStore, Iterator JavaDoc it) {
191         Map JavaDoc diffMap = objectStore.getChangesByObjectId();
192
193         while (it.hasNext()) {
194             Persistent object = (Persistent) it.next();
195
196             int state = object.getPersistenceState();
197
198             // we don't care about NEW objects,
199
// but we still do care about HOLLOW, since snapshot might still
200
// be present
201
if (state == PersistenceState.NEW) {
202                 continue;
203             }
204
205             if (state == PersistenceState.MODIFIED || state == PersistenceState.DELETED) {
206                 // remove cached changes
207
diffMap.remove(object.getObjectId());
208             }
209
210             object.setPersistenceState(PersistenceState.HOLLOW);
211         }
212     }
213 }
214
Popular Tags