blob: b8558aa86bdb4938c1754fa0e250b5be99b95626 [file] [log] [blame]
/*
* Copyright 2001-2008 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.juddi.query;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.uddi.api_v3.ListDescription;
import org.apache.juddi.config.AppConfig;
import org.apache.juddi.config.Property;
import org.apache.juddi.model.TempKey;
import org.apache.juddi.query.util.DynamicQuery;
/**
* @author <a href="mailto:jfaath@apache.org">Jeff Faath</a>
*/
public abstract class EntityQuery {
private static Log log = LogFactory.getLog(EntityQuery.class);
public static final String KEY_NAME = "entityKey";
public static final String TEMP_ENTITY_NAME = "TempKey";
public static final String TEMP_ENTITY_ALIAS = "tk";
public static final String TEMP_ENTITY_PK_TXID_NAME = TEMP_ENTITY_ALIAS + ".pk.txId";
public static final String TEMP_ENTITY_PK_KEY_NAME = TEMP_ENTITY_ALIAS + ".pk.entityKey";
public static final String SIGNATURE_FIELD = "signatures";
public static final int DEFAULT_MAXROWS = 1000;
public static final int DEFAULT_MAXINCLAUSE = 1000;
// TODO: make this alias creator a little more unique
public static String buildAlias(String entityName) {
if (entityName == null || entityName.length() == 0)
return "x";
return entityName.substring(0, entityName.length() - 3) + "_";
}
/*
* Used to retrieve the final results of find operations. Handles paging as specified by user.
*
* TODO: This query will use an IN clause, however, it is not restricted per the global parameter. This is so the query can
* take advantage of sorting through SQL. The fix would be to apply the parameter, but only if the IN list is greater than the
* parameter. In this case, sorting would have to be done in java.
*
*/
public static List<?> getPagedResult(EntityManager em, DynamicQuery dynamicQry, Integer maxRowsUser, Integer listHead, ListDescription listDesc) {
int maxRows = DEFAULT_MAXROWS;
try {
maxRows = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_ROWS, DEFAULT_MAXROWS);
}
catch(ConfigurationException ce) {
log.error("Configuration exception occurred retrieving: " + Property.JUDDI_MAX_ROWS);
}
if (maxRowsUser != null && maxRowsUser > 0) {
if (maxRowsUser < maxRows)
maxRows = maxRowsUser;
}
if (listHead == null || listHead <= 0)
listHead = 1;
Query qry = dynamicQry.buildJPAQuery(em);
List<Object> result = new ArrayList<Object>();
//Filter out non-unique results
for (Object object : qry.getResultList()) {
if (!result.contains(object)) {
result.add(object);
}
}
int resultSize = result.size();
if (listDesc != null) {
listDesc.setActualCount(resultSize);
listDesc.setListHead(listHead);
}
int startIndex = listHead - 1;
if (startIndex >= resultSize) {
if (listDesc != null)
listDesc.setIncludeCount(0);
return Collections.emptyList();
}
else {
int endIndex = Math.min(startIndex + maxRows, resultSize);
if (listDesc != null)
listDesc.setIncludeCount(endIndex - startIndex);
List<Object> subList = new ArrayList<Object>(endIndex);
for (int i=startIndex; i< endIndex; i++) {
subList.add(result.get(i));
}
return subList;
}
}
/*
* Used for all the find operation sub-queries. Restricts size of the IN clause based on global parameter
*/
@SuppressWarnings("unchecked")
public static List<Object> getQueryResult(EntityManager em, DynamicQuery dynamicQry, List<?> keysIn, String inListTerm) {
List<Object> result = new ArrayList<Object>(0);
// 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
// the application property.
if (keysIn == null) {
if (log.isDebugEnabled()) log.debug(dynamicQry);
Query qry = dynamicQry.buildJPAQuery(em);
result = qry.getResultList();
}
else {
int maxInClause = DEFAULT_MAXINCLAUSE;
try {
maxInClause = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_IN_CLAUSE, DEFAULT_MAXINCLAUSE);
}
catch(ConfigurationException ce) {
log.error("Configuration exception occurred retrieving: " + Property.JUDDI_MAX_IN_CLAUSE);
}
if (keysIn.isEmpty()) {
Query qry = dynamicQry.buildJPAQuery(em);
List<Object> resultChunk = qry.getResultList();
result.addAll(resultChunk);
} else {
int inParamsLeft = keysIn.size();
int startIndex = 0;
while(inParamsLeft > 0) {
int endIndex = startIndex + Math.min(inParamsLeft, maxInClause);
List<Object> subKeysIn = new ArrayList<Object>(endIndex);
for (int i=startIndex; i< endIndex; i++) {
subKeysIn.add(keysIn.get(i));
}
dynamicQry.appendInListWithAnd(inListTerm, subKeysIn);
log.debug(dynamicQry);
Query qry = dynamicQry.buildJPAQuery(em);
List<Object> resultChunk = qry.getResultList();
result.addAll(resultChunk);
inParamsLeft = inParamsLeft - (endIndex - startIndex);
startIndex = endIndex;
}
}
}
return result;
}
public static void storeIntermediateKeySetResults (EntityManager em, String txId, List<?> keysIn) {
for (Object key : keysIn) {
TempKey tempKey = new TempKey();
tempKey.setPk(txId,key.toString());
em.persist(tempKey);
}
}
}