This project has retired. For details please refer to its Attic page.
EntityQuery xref
View Javadoc
1   /*
2    * Copyright 2001-2008 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  
18  package org.apache.juddi.query;
19  
20  import java.util.List;
21  import java.util.ArrayList;
22  import java.util.Collections;
23  
24  import javax.persistence.EntityManager;
25  import javax.persistence.Query;
26  
27  import org.apache.commons.configuration.ConfigurationException;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.uddi.api_v3.ListDescription;
31  import org.apache.juddi.config.AppConfig;
32  import org.apache.juddi.config.Property;
33  import org.apache.juddi.model.TempKey;
34  import org.apache.juddi.query.util.DynamicQuery;
35  
36  /**
37   * @author <a href="mailto:jfaath@apache.org">Jeff Faath</a>
38   */
39  public abstract class EntityQuery {
40  	private static Log log = LogFactory.getLog(EntityQuery.class);
41  
42  	public static final String KEY_NAME = "entityKey";
43  	public static final String TEMP_ENTITY_NAME = "TempKey";
44  	public static final String TEMP_ENTITY_ALIAS = "tk";
45  	public static final String TEMP_ENTITY_PK_TXID_NAME = TEMP_ENTITY_ALIAS + ".pk.txId";
46  	public static final String TEMP_ENTITY_PK_KEY_NAME = TEMP_ENTITY_ALIAS + ".pk.entityKey";
47  	public static final String SIGNATURE_FIELD  = "signatures";
48  
49  	public static final int DEFAULT_MAXROWS = 1000;
50  	public static final int DEFAULT_MAXINCLAUSE = 1000;
51  	
52  	// TODO:  make this alias creator a little more unique
53  	public static String buildAlias(String entityName) {
54  		if (entityName == null || entityName.length() == 0)
55  			return "x";
56  		
57  		return entityName.substring(0, entityName.length() - 3) + "_";
58  	}
59  	
60  	/*
61  	 * Used to retrieve the final results of find operations.  Handles paging as specified by user.  
62  	 * 
63  	 * TODO: This query will use an IN clause, however, it is not restricted per the global parameter.  This is so the query can
64  	 * take advantage of sorting through SQL.  The fix would be to apply the parameter, but only if the IN list is greater than the
65  	 * parameter.  In this case, sorting would have to be done in java.
66  	 * 
67  	 */
68  	public static List<?> getPagedResult(EntityManager em, DynamicQuery dynamicQry, Integer maxRowsUser, Integer listHead, ListDescription listDesc) {
69  		
70  		int maxRows = DEFAULT_MAXROWS;
71  		try {
72  			maxRows = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_ROWS, DEFAULT_MAXROWS);
73  		}
74  		catch(ConfigurationException ce) {
75  			log.error("Configuration exception occurred retrieving: " + Property.JUDDI_MAX_ROWS);
76  		}
77  		
78  		if (maxRowsUser != null && maxRowsUser > 0) {
79  			if (maxRowsUser < maxRows)
80  				maxRows = maxRowsUser;
81  		}
82  		
83  		if (listHead == null || listHead <= 0)
84  			listHead = 1;
85  		
86  		
87  		Query qry = dynamicQry.buildJPAQuery(em);
88  		List<Object> result = new ArrayList<Object>();
89  		//Filter out non-unique results
90  		for (Object object : qry.getResultList()) {
91  			if (!result.contains(object)) {
92  				result.add(object);
93  			}
94  		}
95  		
96  		int resultSize = result.size();
97  
98  		if (listDesc != null) {
99  			listDesc.setActualCount(resultSize);
100 			listDesc.setListHead(listHead);
101 		}
102 		
103 		int startIndex = listHead - 1;
104 		if (startIndex >= resultSize) {
105 			if (listDesc != null)
106 				listDesc.setIncludeCount(0);
107 
108 			return Collections.emptyList();
109 		}
110 		else {
111 			int endIndex = Math.min(startIndex + maxRows, resultSize);
112 			if (listDesc != null)
113 				listDesc.setIncludeCount(endIndex - startIndex);
114 
115 			List<Object> subList = new ArrayList<Object>(endIndex);
116 			for (int i=startIndex; i< endIndex; i++) {
117 				subList.add(result.get(i));
118 			}
119 			return subList;
120 		}
121 	}
122 	
123 	/*
124 	 * Used for all the find operation sub-queries.  Restricts size of the IN clause based on global parameter
125 	 */
126 	@SuppressWarnings("unchecked")
127 	public static List<Object> getQueryResult(EntityManager em, DynamicQuery dynamicQry, List<?> keysIn, String inListTerm) {
128 		
129 		List<Object> result = new ArrayList<Object>(0);
130 		// If keysIn is null, then no IN list is applied to the query - we simply need to run the query.  Otherwise, the IN list is chunked based on
131 		// the application property.
132 		if (keysIn == null) {
133 			if (log.isDebugEnabled()) log.debug(dynamicQry);
134 			Query qry = dynamicQry.buildJPAQuery(em);
135 			result = qry.getResultList();
136 		}
137 		else {
138 			int maxInClause = DEFAULT_MAXINCLAUSE;
139 			try {
140 				maxInClause = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_IN_CLAUSE, DEFAULT_MAXINCLAUSE);
141 			}
142 			catch(ConfigurationException ce) {
143 				log.error("Configuration exception occurred retrieving: " + Property.JUDDI_MAX_IN_CLAUSE);
144 			}
145 			if (keysIn.isEmpty()) {
146                             Query qry = dynamicQry.buildJPAQuery(em);
147                             List<Object> resultChunk = qry.getResultList();
148                             result.addAll(resultChunk);
149                         } else {
150                             int inParamsLeft = keysIn.size();
151                             int startIndex = 0;
152                             while(inParamsLeft > 0) {
153                                     int endIndex = startIndex + Math.min(inParamsLeft, maxInClause);
154 
155                                     List<Object> subKeysIn = new ArrayList<Object>(endIndex);
156                                     for (int i=startIndex; i< endIndex; i++) {
157                                             subKeysIn.add(keysIn.get(i));
158                                     }
159                                     dynamicQry.appendInListWithAnd(inListTerm, subKeysIn);
160                                     log.debug(dynamicQry);
161 
162                                     Query qry = dynamicQry.buildJPAQuery(em);
163                                     List<Object> resultChunk = qry.getResultList();
164                                     result.addAll(resultChunk);
165 
166                                     inParamsLeft = inParamsLeft - (endIndex - startIndex);
167                                     startIndex = endIndex;
168                             }
169                         }
170 		}
171 		
172 		return result;
173 		
174 
175 	}
176 	
177 	public static void storeIntermediateKeySetResults (EntityManager em, String txId,  List<?> keysIn) {
178 		
179 		for (Object key : keysIn) {
180 			TempKey tempKey = new TempKey();
181 			tempKey.setPk(txId,key.toString());
182 			em.persist(tempKey);
183 		}
184 	}
185 	
186 }